Asp.net 使用 Graphql-dotnet 上传核心文件



我正在尝试使用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:请求的资源上不存在"访问控制允许源"标头。因此,不允许访问源"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:否 "访问控制允许源"标头存在于请求的上 资源。因此不允许使用原产地"http://localhost:8080" 访问。

此错误表示您需要启用 CORS。

请参阅以下文档:https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1

本质上,您需要以下两样东西:

services.AddCors();
app.UseCors(builder =>
builder.WithOrigins("http://example.com"));

我还建议在 GraphQL.Relay 项目中查看这个Deserializer辅助函数。 它可以帮助您的服务器处理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;
}
}

最新更新