【问题标题】:Can I add [FromBody] parameter with backward compatibility?我可以添加具有向后兼容性的 [FromBody] 参数吗?
【发布时间】:2020-06-02 10:11:30
【问题描述】:

我有没有 [FromBody] 参数的端点:

    [HttpPost("{id:int}/publish")]
    public async Task<IActionResult> Publish()
    {
        <do some stuff>
        return Ok();
    }

但是现在我需要添加 [FromBody] 参数,使旧代码仍然能够在没有参数的情况下使用此端点:

    [HttpPost("{id:int}/publish")]
    public async Task<IActionResult> Publish([FromBody] PublishRequest request)
    {
        <do some stuff>
        return Ok();
    }

但如果我以这种方式添加它并尝试用空主体调用此端点,我会得到 415 (Unsupported Media Type) 响应。

我想让这个更改向后兼容。因此,应该可以在没有请求正文和内容类型标头的情况下使用此端点。有可能吗?

【问题讨论】:

  • 只是好奇:ID参数去哪了?你是如何在你的中提到它的?我会在方法签名上期待它。
  • ATM 似乎不支持可选的FromBody 参数,但似乎在this github 问题中发布了解决方法。
  • 您的问题看起来很像这样:stackoverflow.com/questions/44538772/…您的解决方案是否允许使用 [FromForm] 而不是 [FromBody]?
  • @GuruStron,这正是我所需要的!您可以发表您的评论作为答案,我会投赞成票!
  • @ant 很高兴它有帮助!添加为答案。

标签: .net asp.net-core .net-core


【解决方案1】:

ATM 似乎不支持可选的FromBody 参数,但在这个github 问题中发布了一个可能的解决方法:

public class SomeClassModelBinder : IModelBinder
{
    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var stream = bindingContext.HttpContext.Request.Body;
        string body;
        using (var reader = new StreamReader(stream))
        {
            body = await reader.ReadToEndAsync();
        }
        var someClass = JsonConvert.DeserializeObject<SomeClass>(body);

        bindingContext.Result = ModelBindingResult.Success(someClass);
    }
}

[FromBody, ModelBinder(BinderType = typeof(SomeClassModelBinder))] SomeClass request,

【讨论】:

    【解决方案2】:

    您可以将 PublishRequest 设为可选。

    [HttpPost("{id:int}/publish")]
    public async Task<IActionResult> Publish([FromBody] PublishRequest? request)
    {
        // <do some stuff>
        return Ok();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 2021-10-10
      • 1970-01-01
      相关资源
      最近更新 更多