asp.net core 3.0 web api request.body和[frombody]冲突[关闭]

Posted

技术标签:

【中文标题】asp.net core 3.0 web api request.body和[frombody]冲突[关闭]【英文标题】:asp.net core3.0 webapi request.body and [frombody] conflict [closed] 【发布时间】:2020-01-05 09:40:35 【问题描述】:

需要在frombody之后通过request.body获取body,但是测试了2天也没找到解决办法。我添加了Request.EnableBuffering()

// PUT: api/Test/5
[HttpPut("id")]
public async Task<string> PutAsync(int id, [FromBody]ProductInfo value)

    var ccccc = "";
    Request.EnableBuffering();
    using (var reader = new StreamReader(Request.Body, encoding: System.Text.Encoding.UTF8))
    
        var body = await reader.ReadToEndAsync();
        ccccc = body;
        Request.Body.Position = 0;
    
    return ccccc;

【问题讨论】:

你遇到了什么错误? 请同时提供 ProductInfo 定义并说明您要达到的目标 【参考方案1】:

我相信你遇到的问题是你的cccc 回来是空的。这可能是因为当您进入控制器时,请求正文流已经被读取。这是有道理的 - 必须为您填充 value 参数。所以在这个阶段尝试倒带已经太迟了。

ASP.NET Blog 有一篇关于如何解决此问题的文章:您需要一个自定义中间件,并且需要将其插入到 MVC 中间件上方的管道中。

Startup.cs

public void ConfigureServices(IServiceCollection services)

    services.AddTransient<CustomMiddleware>(); // register your custom middleware with DI container
    services.AddControllers();


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseMiddleware<CustomMiddleware>(); // inject your middleware before MVC injects theirs

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    
        endpoints.MapControllers();
    );

那么您的自定义中间件可能如下所示:

CustomMiddleware.cs

public class CustomMiddleware : IMiddleware

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    
        context.Request.EnableBuffering(); // now you can do it

        // Leave the body open so the next middleware can read it.
        using (var reader = new StreamReader(context.Request.Body, encoding: Encoding.UTF8, detectEncodingFromByteOrderMarks: false, leaveOpen: true))
        
            var body = await reader.ReadToEndAsync();
            context.Items.Add("body", body); // there are ways to pass data from middleware to controllers downstream. this is one. see https://***.com/questions/46601757/c-sharp-dotnet-core-2-pass-data-from-middleware-filter-to-controller-method for more

            // Reset the request body stream position so the next middleware can read it
            context.Request.Body.Position = 0;
        

        // Call the next delegate/middleware in the pipeline
        await next(context);
    

最后在您的控制器中,您将从context 获取正文,如下所示:

// PUT: api/Test/5
[HttpPut("id")]
public async Task<string> PutAsync(int id, [FromBody]ProductInfo value)
            
    var ccccc = (string)HttpContext.Items["body"];
    return ccccc;

此方法附带一些注意事项,本文将对此进行讨论。注意巨大的请求体并相应地调整缓冲区大小。

【讨论】:

以上是关于asp.net core 3.0 web api request.body和[frombody]冲突[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 ASP.NET Core 3.0 内置 API 从 .crt 和 .key 文件创建 X509Certificate2

将 OpenID Connect 与 .NET Core 3.0 ASP.NET Core API 服务一起使用时出错

使用 OData 的 ASP.Net Core Web API 实现对于单个实体 URI 失败

新的 ASP.NET Core 3.0 Json 序列化器遗漏了数据

asp.net web.Config 配置httpHandlers无效 求解,在线等!

深入研究 Angular 和 ASP.NET Core 3.0