为什么 FromBody 会这样?

Why FromBody Behave like this ?

我想了解为什么 FromBody 对于常见请求会有这样的行为。

案例一:

控制器

public void Post([FromBody]string value)
        {
        }

POSTMAN 请求

问题 在这种情况下,值是我的 post 方法不会绑定到要测试的值参数。

案例二:

型号

public class Test
    {
        public string value { get; set; }
    }

控制器

public void Post([FromBody]Test model)
        {
        }

POSTMAN 请求 同案例一

结果: 现在模型值 属性 成功绑定到“test”。

为什么会这样?

因为 API 就是这样设计的。请注意,在您的第二个示例中,您可以省略 [FromBody] 并且 WebApi 无论如何都会在正文中搜索数据,因为 Test 是一个复杂类型。

本文讲解WebApi绑定数据的规则:

http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

编辑: 正如所评论的那样,上面链接的文章清楚地表明你应该能够做到

void Get([FromBody]string value)

正确的,但这意味着您可以将正文的值作为纯文本读入参数值。这意味着如果你走这条路,你必须使用原始选项(来自邮递员)并清除 Content-Type 或确保它设置为 text/plain.

换句话说,在 Postman 上,如果您将发送方法设置为 raw,并在提供的文本区域中按原样输入 "this is a sentence",当以下问题得到解决时,您的值将是 "this is a sentence".

现在,如果您尝试从新模板执行此操作,您将 运行 出现此错误:

{
    "Message": "The request entity's media type 'text/plain' is not supported for this resource.",
    "ExceptionMessage": "No MediaTypeFormatter is available to read an object of type 'String' from content with media type 'text/plain'.",
    "ExceptionType": "System.Net.Http.UnsupportedMediaTypeException",
    "StackTrace": "   at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n   at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n   at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"
}

本文解释了如何让 WebApi 接受来自正文的 text/plain 数据:

https://myadventuresincoding.wordpress.com/2012/06/19/c-supporting-textplain-in-an-mvc-4-rc-web-api-application/

默认的 ValuesController 公开了具有该签名的方法,但没有为 text/plain 提供 MediaTypeFormatter,这有点愚蠢,但我想这就是 Microsoft 为您准备的。

鉴于此方法:

// POST api/values
[HttpPost]
public void Post([FromBody]string value)
{
    Values.Add(value);
}

必须正确配置 Postman 才能使我们的值绑定到其 C# string 对象...确保在我们的案例中有效的一种方法是向我们的服务器发送 JSON 请求.请按照以下步骤操作:

  • 确保你已经select编辑了POST
  • 确保您输入了合适的 URL,即 http://localhost:1337/api/values
  • 转到 Body,勾选 raw 的选项。
  • 在右侧的下拉列表中,select JSON (application/json)
  • 在Postman的文本区,只插入"Hello, world."加上引号,否则无效JSON)。

一旦您点击 Send,它现在应该可以工作了。

对于 JSON 你可以这样做:

    public HttpResponseMessage Webhook(JToken json)
    {

    }

其中 JTokenNewtonsoft.Json.Linq.JToken

JObject 如果数据是实际的 JSON 对象(不是数组)