使用 Relay 和 graphql-dotnet 上传文件
File Upload with Relay and graphql-dotnet
我正在尝试在包含文件的中继中构建一个突变。一旦我实施了此处引用的 getFiles()
方法:https://facebook.github.io/relay/docs/api-reference-relay-mutation.html#getfiles
中继发送多部分请求,导致来自 ASP.NET Core MVC 的 415 错误。
我正在寻找一个工作示例,类似于“How would you do file uploads in a React-Relay app?" with the graphql-dotnet library。
您是否只是不知道如何访问服务器上解析器中的文件?您可以将文件作为 rootObject
或 userContext
.
传递
// GraphQLController
var files = Request.Form.Files;
var userContext = files;
var result = await executer.ExecuteAsync(
schema,
rootObject,
query,
operationName,
inputs,
userContext).ConfigureAwait(false);
// Mutation type
Field<StringGraphType>(
"uploadFile",
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<StringGraphType>> {Name = "fileName"}),
resolve: context =>
{
var userContext = context.UserContext.As<IFormFileCollection>();
// process files
// return data
return "success";
});
GraphQL 端点不接受多部分表单 mimetype,因为它不是 JSON。一旦我通过 RootObject 和突变中可用的上下文将它们放入 graphql-dotnet 中,我就能够使用这些文件。让我失望的是 MVC。
所以我写了一个简单的过滤器:
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;
}
}
}
已注册:
services.AddScoped<RelayResourceFilter>();
然后在控制器中像这样应用它:
[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
}
我正在尝试在包含文件的中继中构建一个突变。一旦我实施了此处引用的 getFiles()
方法:https://facebook.github.io/relay/docs/api-reference-relay-mutation.html#getfiles
中继发送多部分请求,导致来自 ASP.NET Core MVC 的 415 错误。
我正在寻找一个工作示例,类似于“How would you do file uploads in a React-Relay app?" with the graphql-dotnet library。
您是否只是不知道如何访问服务器上解析器中的文件?您可以将文件作为 rootObject
或 userContext
.
// GraphQLController
var files = Request.Form.Files;
var userContext = files;
var result = await executer.ExecuteAsync(
schema,
rootObject,
query,
operationName,
inputs,
userContext).ConfigureAwait(false);
// Mutation type
Field<StringGraphType>(
"uploadFile",
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<StringGraphType>> {Name = "fileName"}),
resolve: context =>
{
var userContext = context.UserContext.As<IFormFileCollection>();
// process files
// return data
return "success";
});
GraphQL 端点不接受多部分表单 mimetype,因为它不是 JSON。一旦我通过 RootObject 和突变中可用的上下文将它们放入 graphql-dotnet 中,我就能够使用这些文件。让我失望的是 MVC。
所以我写了一个简单的过滤器:
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;
}
}
}
已注册:
services.AddScoped<RelayResourceFilter>();
然后在控制器中像这样应用它:
[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
}