C# 如何在ASP.NET Core中设置请求的内容类型?

C# 如何在ASP.NET Core中设置请求的内容类型?,c#,asp.net-core,C#,Asp.net Core,我尝试设置未命中边界的multipart/formdataGET请求的内容类型。我尝试过以下代码: public class BoundaryMiddleware { private readonly RequestDelegate _next; public BoundaryMiddleware(RequestDelegate next) { this._next = next; } public async Task Invoke(

我尝试设置未命中边界的
multipart/formdata
GET请求的内容类型。我尝试过以下代码:

public class BoundaryMiddleware
{
    private readonly RequestDelegate _next;

    public BoundaryMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path.Value.Contains("api/webhook"))
        {  
            if (context.Request.ContentType == "multipart/form-data")
            { 
                context.Request.ContentType = $"multipart/form-data; boundary=\"{Guid.NewGuid()}\""; 
            }
        }

        await _next.Invoke(context);
    }
}
和启动文件:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
        ILoggerFactory loggerFactory,
        IConfiguration configuration)
    {
        loggerFactory.AddDebug();
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            loggerFactory.AddDebug();
        }

        app.UseMiddleware<BoundaryMiddleware>();

        app.UseMvc();
    }
}
编辑2:如果我按原样发送请求,则会引发此异常:

System.IO.InvalidDataException: Missing content-type boundary.
   at Microsoft.AspNetCore.Http.Features.FormFeature.GetBoundary(MediaTypeHeaderValue contentType, Int32 lengthLimit)
   at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext context)
   at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext actionContext, IList`1 factories)
   at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
System.IO.InvalidDataException:缺少内容类型边界。
位于Microsoft.AspNetCore.Http.Features.FormFeature.GetBoundary(MediaTypeHeaderValue contentType,Int32 lengthLimit)
在Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken CancellationToken)上
位于Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext)
位于Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext ActionContext,IList`1工厂)
位于Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ControllerContext ControllerContext)
在Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.c_uuDisplayClass0_0.d.MoveNext()中
---来自引发异常的上一个位置的堆栈结束跟踪---
在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()中
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()上
位于Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext)
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State&Next、Scope&Scope、Object&State、Boolean&isCompleted)
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()中
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()上
在Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext HttpContext)中

对于HTTP,获取内容类型HTTP头应该无关紧要,内容类型HTTP头将在带有主体的请求上设置(通常是PUT和POST)

确实可以用一个getbody,看看你的API是否需要支持那好运,但也不是不可能

否则,如果API使用者不发送正文,请执行以下操作:

[AllowAnonymous]
[HttpGet]
[Route("api/webhook")]
public IActionResult GetWebhook()
{
     // rock and roll 
     return Ok();
}
使用卷曲测试(使用本地


不需要该请求拦截器。

.Net HTTP头通常有点滑稽,框架在尝试将原始HTTP请求转换为
HttpRequest
时会做出各种假设,然后在调用控制器上的操作时会进行进一步处理

由于没有主体,所以使用内容类型头或边界值没有什么意义。您可能会发现完全删除标题更有效

public async Task Invoke(HttpContext context)
{
    if (context.Request.Path.Value.Contains("api/webhook"))
    {  
        if (context.Request.ContentType == "multipart/form-data")
            context.Request.Headers.Remove("Content-Type");            
    }

    await _next.Invoke(context);
}

如果没有对服务的调用,您的问题很难回答,从错误来看,流似乎已经被读取,您需要在尝试读取之前将流设置为开头。为什么需要插入该Id?我的意思是,你可以在你的控制器动作中做到这一点,让路由做他的事情,你不能只是添加一个随机的边界标识符。该标识符必须在整个请求主体中使用,才能使其发挥作用如果客户端生成错误的请求,为什么不尝试修复它?我不是调用api的代码的所有者,请求是get请求,因此正文不包含任何内容。作为get的内容多部分/表单数据?我错过什么了吗?
[AllowAnonymous]
[HttpGet]
[Route("api/webhook")]
public IActionResult GetWebhook()
{
     // rock and roll 
     return Ok();
}
curl -X GET "https://localhost:44395/api/webhook" -H "content-type: multipart/form-data" --verbose
public async Task Invoke(HttpContext context)
{
    if (context.Request.Path.Value.Contains("api/webhook"))
    {  
        if (context.Request.ContentType == "multipart/form-data")
            context.Request.Headers.Remove("Content-Type");            
    }

    await _next.Invoke(context);
}