0

I'm trying to upload the user avatar of .png/jpeg/.jpg file types from angular client to .netCore server application using GraphQL API. I managed to send the image to be uploaded in a request of content type multipart/form-data from client-side. But getting a 400 Error from the API server saying the content-type is not supported.

Error message is as follows:

message: "Invalid 'Content-Type' header: non-supported media type. Must be of 'application/json', 'application/graphql' or 'application/x-www-form-urlencoded'. See: http://graphql.org/learn/serving-over-http/."

I'm trying to implement the mutation like this.

FieldAsync<StringGraphType>(
            "testImageUpload",
            arguments: new QueryArguments(
                new QueryArgument<StringGraphType> { Name = "testArg" },
                new QueryArgument<UploadGraphType> { Name = "file" }
                ),
            resolve: async context =>
            {
                var testArg = context.GetArgument<string>("testArg");
                var file = context.GetArgument<IFormFile>("file");

                try
                {
                    return await uploaderService().UploadImage(file);
                }
                catch (Exception e)
                {
                    context.Errors.Add(new ExecutionError("Something happened!"));
                    return context.Errors;
                }
            });

I'm using GraphQL.net and GraphQL.Upload.AspNetCore for supporting multipart files.

Sample mutation will be like this:

mutation testImageUpload($testArg: String, $file: Upload) {
  fileUpload{
    testImageUpload(testArg: $testArg, file: $file)
  }
}

Can anybody suggest to me how to make the .NetCore webAPI application accept multipart/form-data. Any help will be appreciated. Thanks in advance.

1 Answers1

0

I, too, ran into this issue. The answer lies within your Startup.cs file.

First, the reason for which the "Invalid 'Content-Type' header" appears even while using GraphQL.Upload is because (at the time of this answer) the GraphQL.net middleware only checks for the three different Content-Type headers and errors out if none of those match. See GitHub

As for the solution, you haven't shared any of your Startup.cs file so I'm not sure what yours looks like. I'll share the relevant pieces of mine.

You'll need to add the service and the middleware.

The service:

services.AddGraphQLUpload()
  .AddGraphQL((options, provider) =>
  {
  ...
  });

If you're using a endpoints to map to a middleware, you'll need to add the UseGraphQLUpload middleware, then map your endpoint.

Example:

  app.UseGraphQLUpload<YourSchema>("/api/graphql", new 
  GraphQLUploadOptions {
    UserContextFactory = (ctx) => new GraphQlUserContext(ctx.User)
  });
  app.UseEndpoints(endpoints =>
  {
    // map HTTP middleware for YourSchema at path api/graphql
    endpoints
      .MapGraphQL<YourSchema, GraphQLMiddleware<YourSchema>>("api/graphql")
      .RequireAuthorization();
    ...
    // Additional endpoints
    ...
   }

Everything else looks fine to me.

Dharman
  • 30,962
  • 25
  • 85
  • 135