控制器操作未从 JSON 读取 Guid POST

Posted

技术标签:

【中文标题】控制器操作未从 JSON 读取 Guid POST【英文标题】:Controller action not reading Guid POST from JSON 【发布时间】:2016-05-24 03:14:48 【问题描述】:

我有一个控制器动作声明为:

[Route("api/person")]
[HttpPost]
public async Task<IActionResult> Person([FromBody] Guid id)  ... 

我发帖给它:

POST /api/person HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 747a5d76-398c-e1c7-b948-b276bb24976c


    "id": "b85f75d8-e6f1-405d-90f4-530af8e060d5"

我的操作被击中,但它接收到的 Guid 始终是 Guid.Empty 值(即:它没有得到我传递的值)。

注意,如果我使用 url 参数而不是 [FromBody],这可以正常工作,但我想使用 http 帖子的正文。

【问题讨论】:

id 不应该是原始 JSON 字符串而不是对象吗?所以只是“b85f75d8-e6f1-405d-90f4-530af8e060d5”? 另外,传入一个字符串,然后将 TryParse 传递给 Guid。我会在我的机器上测试这个,但我的 VS 正在安装。 不错的主意。我正在使用移动设备,但会在早上进行测试。 【参考方案1】:

如Web API documentation中所述:

默认情况下,Web API 使用以下规则绑定参数:

如果参数是“简单”类型,Web API 会尝试从 URI 中获取值。简单类型包括 .NET 原始类型(int、 bool、double 等),以及 TimeSpan、DateTime、Guid、decimal、 和字符串,加上任何带有类型转换器的类型,可以从 一个字符串。 (稍后会详细介绍类型转换器。) 对于复杂类型,Web API 尝试使用媒体类型格式化程序从消息正文中读取值。

使用 [FromBody] 部分的同一篇文章中,您可以看到可以在参数上添加属性[FromBody] 以绑定请求正文中的值的示例,就像你做到了。但这里有一个问题 - 示例显示,在这种情况下,请求正文应该包含原始值,而不是 JSON 对象。

所以在你的情况下,你有两个选择:

第一个选项是更改您的请求以提供原始值而不是 JSON 对象

POST /api/person HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 747a5d76-398c-e1c7-b948-b276bb24976c

"b85f75d8-e6f1-405d-90f4-530af8e060d5"

第二种选择是提供具有单一属性的复杂对象并将其用作参数:

public class Request

    public Guid Id  get; set; 


[Route("api/person")]
[HttpPost]
public async Task<IActionResult> Person([FromBody] Request request)  ... 

【讨论】:

您说“第一个选项是更改您的请求以提供原始值而不是 JSON 对象”,但在您给出的示例中,上下文类型:application/json。 在第二个选项中,您仍然需要为它提供一个 Guid,但又失败了: "Request": "Id":"e01b8040-8fd7-4227-a55a-111111111111" 跨度>

以上是关于控制器操作未从 JSON 读取 Guid POST的主要内容,如果未能解决你的问题,请参考以下文章

$_POST 未从 Javascript 的 Fetch() 中检索数据

Mongoose Express API 未从 req.body 读取

POST 路由未从根路径 Laravel 5.2 中列出

未从提取的 API 数据中获取正确的 JSON 格式 [关闭]

React 应用程序未从 Express 服务器接收 res.data (JSON),尽管 Postman 确实如此

使用 JSON 时如何让 ServiceStack 用破折号格式化 Guid?