The GraphQL Endpoint wasn't accepting the multi-part form mimetype because it wasn't JSON. I was able to work with the files once I got them into graphql-dotnet via the RootObject and the context that's available in the mutation. What was throwing me off was MVC.
So I wrote a simple Filter:
public class RelayResourceFilter : IResourceFilter
{
private readonly string jsonMediaType = "application/json";
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
if (!string.Equals(MediaTypeHeaderValue.Parse(context.HttpContext.Request.ContentType).MediaType,
this.jsonMediaType, StringComparison.OrdinalIgnoreCase))
{
var encoder = JavaScriptEncoder.Create();
var variables = encoder.Encode(context.HttpContext.Request.Form["variables"]);
var query = encoder.Encode(context.HttpContext.Request.Form["query"]);
var body = $"{{\"query\":\"{query}\", \"variables\":\"{variables}\"}}";
byte[] requestData = Encoding.UTF8.GetBytes(body);
context.HttpContext.Request.Body = new MemoryStream(requestData);
context.HttpContext.Request.ContentType = this.jsonMediaType;
}
}
}
registered it:
services.AddScoped<RelayResourceFilter>();
and then applied it like so in the Controller:
[ServiceFilter(typeof(RelayResourceFilter))]
public async Task<ExecutionResult> Post([FromBody]GraphQLQuery query, bool? useErrorCode)
{
var files = this.Request.HasFormContentType ? this.Request.Form.Files : null;
// ... assignment to Root Object
}