reactjs - 使用 Graphql-dotnet 上传 Asp.net 核心文件
问题描述
我正在尝试使用graphql-dotnet上传图像文件,但它从未成功。
我在我的 GraphQLController 中获取文件对象:
var files = this.Request.Form.Files;
var executionOptions = new ExecutionOptions
{
Schema = _schema,
Query = queryToExecute,
Inputs = inputs,
UserContext = files,
OperationName = query.OperationName
};
这里是我的突变:
Field<UserGraphType>(
"uploadUserAvatar",
Description="Kullanıcı resmi yükleme.",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "Id", Description = "Identity Alanı" }
),
resolve: context => {
var file = context.UserContext.As<IFormCollection>();
var model = userService.UploadAvatar(context.GetArgument<int>("Id"),file);
return true;
}
);
我认为它接受唯一的 JSON。它不接受请求作为文件类型。
我也在客户端使用 React 和 apollo-client。它在控制台中有一个错误:
无法加载http://localhost:5000/graphql:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“ http://localhost:8080 ”。响应的 HTTP 状态代码为 500。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
我正在尝试发送这样的查询:
const { selectedFile,id } = this.state
this.props.uploadAvatar({
variables: {id},
file:selectedFile
}).then(result => {
console.log(result);
});
我能做些什么来实现这一目标?
解决方案
无法加载http://localhost:5000/graphql:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“ http://localhost:8080 ”。
此错误意味着您需要启用 CORS。
请参阅这些文档:https ://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1
基本上你需要这两件事:
services.AddCors();
app.UseCors(builder =>
builder.WithOrigins("http://example.com"));
我还建议Deserializer
在 GraphQL.Relay 项目中查看这个辅助函数。它可以帮助您的服务器处理multipart/form-data
请求。然后,您可以使用解析的查询信息和文件并将其传递给DocumentExecutor
.
https://github.com/graphql-dotnet/relay/blob/master/src/GraphQL.Relay/Http/Deserializer.cs
public static class Deserializer
{
public static async Task<RelayRequest> Deserialize(Stream body, string contentType)
{
RelayRequest queries;
switch (contentType)
{
case "multipart/form-data":
queries = DeserializeFormData(body);
break;
case "application/json":
var stream = new StreamReader(body);
queries = DeserializeJson(await stream.ReadToEndAsync());
break;
default:
throw new ArgumentOutOfRangeException($"Unknown media type: {contentType}. Cannot deserialize the Http request");
}
return queries;
}
private static RelayRequest DeserializeJson(string stringContent)
{
if (stringContent[0] == '[')
return new RelayRequest(
JsonConvert.DeserializeObject<RelayQuery[]>(stringContent),
isBatched: true
);
if (stringContent[0] == '{')
return new RelayRequest() {
JsonConvert.DeserializeObject<RelayQuery>(stringContent)
};
throw new Exception("Unrecognized request json. GraphQL queries requests should be a single object, or an array of objects");
}
private static RelayRequest DeserializeFormData(Stream body)
{
var form = new MultipartFormDataParser(body);
var req = new RelayRequest()
{
Files = form.Files.Select(f => new HttpFile {
ContentDisposition = f.ContentDisposition,
ContentType = f.ContentType,
Data = f.Data,
FileName = f.FileName,
Name = f.Name
})
};
req.Add(new RelayQuery {
Query = form.Parameters.Find(p => p.Name == "query").Data,
Variables = form.Parameters.Find(p => p.Name == "variables").Data.ToInputs(),
});
return req;
}
}
推荐阅读
- javascript - 在点和双空格后拆分纯文本字符串
- flutter - 颤振通知中没有振动
- vba - 如何从 Word VBA 设置 Outlook 来自电子邮件地址
- python - Jupyter Notebook 中的 Python 包版本(散景)与终端中的版本不同
- google-bigquery - BigQuery - 分区必要性
- arrays - 试图在我的登录页面中打印状态
- micronaut - Micronaut 中的 EventBus 支持
- oracle - Postgres 中 TG_OP 和 TG_NAME 的 Oracle 等价物是什么?
- c - 在 C 中读取具有不均匀大小的立方体和额外字符的迷宫文件的数组
- php - 将自定义字段添加到 woo 产品页面(仅适用于某些产品 id)