【发布时间】:2019-08-30 15:45:01
【问题描述】:
我有一个旧版 .Net Framework 客户端,其中有很多无法更改的安装。我需要处理用于将文件上传到服务器的 http post 请求。
以前我们可以使用 HttpContext.Request.Files。但是由于我们现在使用的是 dotnet core,所以我们必须使用 HttpContext.Request.Form.Files。这是抛出一个excaption
“值不能为空。参数名称:header”堆栈跟踪如下
在 Microsoft.Net.Http.Headers.ContentDispositionHeaderValueIdentityExtensions.IsFileDisposition(ContentDispositionHeaderValue 标题)在 Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken 取消令牌)在 Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm() 在 Microsoft.AspNetCore.Http.Internal.DefaultHttpRequest.get_Form()
在github上查看asp dotnet core的源码,我可以在第26行看到确切的问题here。
return header.DispositionType.Equals("form-data")
&& (!StringSegment.IsNullOrEmpty(header.FileName) || !StringSegment.IsNullOrEmpty(header.FileNameStar));
我认为这是客户端将标头信息添加到文件而不是请求本身的问题,但是当我添加一些中间件(如下)以将该标头添加到我的请求时,HttpContext.Request。表单仍然抛出异常。我不知道创建时是否引发了此异常,或者我没有正确设置标头,或者这是否是 dotnet 核心中的错误。 github 上有一些未解决的问题来改进错误消息,但没有任何迹象表明他们的代码是问题所在。
我只想“修复”标头,因为我知道对该端点的调用将始终是多部分表单数据,理想情况下使用中间件,因此控制器不必处理它。
中间件:
public class FormDataHeaderRepair
{
private readonly RequestDelegate _next;
public FormDataHeaderRepair(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var headers = context.Request.Headers;
if (context.Request.Path.ToString().Equals("/api/MyController/Queue", StringComparison.OrdinalIgnoreCase))
{
if (context.Request.Headers["Content-Disposition"].Count == 0)
{
var cv = new Microsoft.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
cv.FileName = "request.xml";
var stringVersion = cv.ToString();
context.Request.Headers[HeaderNames.ContentDisposition] = stringVersion;
}
}
await _next(context);
}
}
编辑/更新:将此代码添加到我的控制器,为“theResult”返回“true”,这让我认为 ContentDispositionHeaderValueIdentityExtensions 正在使用其他一些缓存的请求/标头集合,因为这是他们的确切评估代码正在使用...或者他们正在以与此不同的方式检索标头。
var header = HttpContext.Request.GetTypedHeaders().ContentDisposition;
var theResult = header.DispositionType.Equals("form-data") && (!StringSegment.IsNullOrEmpty(header.FileName) || !StringSegment.IsNullOrEmpty(header.FileNameStar));
【问题讨论】:
-
您是添加中间件作为第一个中间件还是至少在
app.UseMvc之前添加?否则它可能会为时已晚地操纵标题。 -
我想我在最后添加了它!谢谢,我根本没想过。将尝试并报告回来。编辑:它已经在 MVC 之前。该死的。
标签: c# asp.net-core .net-core