如果没有内容类型标头,asp.net核心http删除`FromBody`

时间:2018-07-15 11:29:37

标签: c# http asp.net-core

我正在http DELETE请求中使用正文。我知道目前删除主体是不规范的(但可以)。

使用HttpClient时出现问题,该{不允许使用正文来进行删除请求。我知道我可以只使用SendAsync,但我想让我的API更灵活。

我希望此主体是可选的。从某种意义上说,如果asp.net core无法确定内容类型,则将其忽略。此刻,即使没有发送任何正文(通过HttpClient-因此内容长度应为0),asp.net核心仍返回415。

可以FromBody以这种方式扩展吗?还是我需要管道中的一些自定义逻辑?

3 个答案:

答案 0 :(得分:1)

您可以创建ResourceFilter,该模型在检查内容类型的“模型绑定”之前执行:

<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker </title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
  <script src="app2.js"></script>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>

<body ng-app="plunker">
  <div ng-controller="MainCtrl as ctrl">

    <button ng-click="openModal()">Open the modal please</button>
    <br>
    <br>
    <p>modalresult = {{modalresult}} </p>

  </div>
</body>

</html>

并将其添加到您的方法中

public class AddMissingContentType : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        context.HttpContext.Request.Headers["Content-Type"] = "application/json";
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
    }
}

答案 1 :(得分:0)

一种解决方案是使用控制器方法手动获取主体。您可以检查内容类型是否存在,或者只使用默认阅读器(例如json),然后将其转换为模型。然后,您无需修改​​任何请求标头

[HttpDelete]
public async Task Delete()
{
    using (StreamReader reader = new StreamReader(request.Body, encoding))
    {
        var bodyContent = await reader.ReadToEndAsync();
        if(!String.IsNullOrEmpty(bodyContent))
        {
            //mapp the bodyContent to your model
        }
    }
    //perform the logic which should allways be done
}

注意:在方法签名中省略FromBody参数很重要,否则当内容类型或正文丢失时绑定将失败

答案 2 :(得分:0)

如果您将〜app用作代理,负载均衡器或其他您无法控制的东西背后的API,则可以将其转换为POST

示例:某些负载平衡器可以考虑主体格式不正确的DELETE方法。 但是,如果您确定自己将来的环境,为什么不...

编辑:答案是:即使有可能,也许最好遵循有时应用的规则,有时不要再感到意外。 (-无法评论我是新出生的用户)。