关于c#:FromBody字符串参数为null

FromBody string parameter is giving null

这可能是非常基本的东西,但是我很难弄清楚哪里出了问题。

我正在尝试从POST正文中获取一个字符串,但" jsonString"仅显示为null。 我也想避免使用模型,但这也许是不可能的。 我用PostMan打的那段代码是这个块:

1
2
3
4
5
6
[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] string jsonString)
{
    ...
}

也许这是我对邮递员做的不正确的事情,但是我一直在尝试尝试在正文的值部分使用" = test"(在有关此主题的其他问题中看到)-x-www-form-urlencoded部分与 密钥为jsonString,什么也没有。 我也尝试过使用原始文本和原始文本/纯文本。 我获得了ID,因此我知道网址是正确的。 任何帮助,将不胜感激。

目前,PostMan的设置如下:

1
2
3
4
POST http://localhost:8000/Edit/Test?id=111
key = id  value = 111
Body - x-www-form-urlencoded
key = jsonString  value ="=test"


在ASP.NET Web API中引用参数绑定

Using [FromBody]

To force Web API to read a simple type from the request body, add the
[FromBody] attribute to the parameter:

1
2
3
[Route("Edit/Test")]
[HttpPost]
public IHttpActionResult Test(int id, [FromBody] string jsonString) { ... }

In this example, Web API will use a media-type formatter to read the
value of jsonString from the request body. Here is an example client
request.

1
2
3
4
5
6
7
POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/json
Content-Length: 6

"test"

When a parameter has [FromBody], Web API uses the Content-Type header
to select a formatter. In this example, the content type is
"application/json" and the request body is a raw JSON string (not a
JSON object).

在上面的示例中,如果在主体中以正确的格式提供数据,则不需要模型。

对于URL编码,请求看起来像这样

1
2
3
4
5
6
7
POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

=test


通过使用[FromBody]声明jsonString参数,您可以使ASP.NET Core使用输入格式器将提供的JSON(或XML)绑定到模型。因此,如果您提供一个简单的模型类,那么您的测试应该可以工作

1
2
3
4
5
6
7
8
9
10
11
public class MyModel
{
    public string Key {get; set;}
}

[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] MyModel model)
{
    ... model.Key....
}

和一个发送的JSON

1
2
3
{
    key:"value"
}

当然,您可以通过访问控制器中的HttpContext.Request来跳过模型绑定并直接检索提供的数据。 HttpContext.Request.Body属性为您提供内容流,或者您可以通过HttpContext.Request.Forms访问表单数据。

由于类型安全,我个人更喜欢模型绑定。


当具有[FromBody]属性时,发送的字符串不应为原始字符串,而应为JSON字符串,因为它包含包装引号:

1
"test"

基于https://weblog.west-wind.com/posts/2017/Sep/14/Accepting-Raw-Request-Body-Content-in-ASPNET-Core-API-Controllers

在ASP.NET Web API中使用FromBody时,类似的答案字符串值为空。


就我而言,我忘了使用

1
JSON.stringify(bodyStuff).

您走在正确的轨道上。

在标题集上

1
Content-Type: application/x-www-form-urlencoded

POST请求的主体应为=test,且别无其他。对于未知/可变字符串,必须对值进行URL编码,以免出现输入字符意外转义的情况。

另请参见ASP.NET Web Api应用程序的POST字符串-返回null


经过1小时的努力,终于让它开始工作。

这将消除null问题,并以通用方式(无模型绑定)获取JSON key1的value1值。

对于新的WebApi 2应用程序示例:

Postman (looks exactly, like below):

1
2
3
4
POST    http://localhost:61402/api/values   [Send]
Body
     (*) raw             JSON (application/json) v
        "{  \"key1\": \"value1\" }"

端口61402或上面的url / api / values可能与您不同。

ValuesController.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using Newtonsoft.Json;
// ..

// POST api/values
[HttpPost]
public object Post([FromBody]string jsonString)
{
    // add reference to Newtonsoft.Json
    //  using Newtonsoft.Json;

    // jsonString to myJsonObj
    var myJsonObj = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);

    // value1 is myJsonObj[key1]
    var valueOfkey1 = myJsonObj["key1"];

    return myJsonObj;
}

现在一切都很好,不确定我是否有子键是否需要将模型绑定到类,或者子键上的DeserializeObject是否可以工作。


我知道这个答案有点旧,有一些很好的答案已经解决了这个问题。为了解决这个问题,我想再说一件事,在过去的4到5个小时里,我发疯了。

在模型类中的属性启用set属性非常非常重要。

这将不起作用(参数仍然为空):

1
2
3
4
5
6
7
8
9
10
/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
    return form;
}
/* Model class code */
public class Weird {
    public string UserId {get;}
    public string UserPwd {get;}
}

这将工作:

1
2
3
4
5
6
7
8
9
10
/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
    return form;
}
/* Model class code */
public class Weird {
    public string UserId {get; set;}
    public string UserPwd {get; set;}
}


使用原始JSON发布字符串,并且不要忘记双引号!

enter image description here


经过漫长的噩梦,摆弄了Google并尝试了Stack Overflow中的错误代码,我发现将[[FromBody]字符串模型)更改为[[FromBody]对象模型)确实感到奇怪,请问我不是在使用.NET 4.0吗?是的,我知道很老但是...


如果您不希望/不需要绑定到具体的类,则可以将JSON直接传递给WebAPI控制器。控制器可以使用ExpandoObject类型接受JSON。这是方法示例:

1
2
3
4
public void Post([FromBody]ExpandoObject json)
{
    var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)json);
}

将Content-Type标头设置为application / json并将JSON作为正文发送。 keyValuePairs对象将包含JSON键/值对。

或者,您可以让该方法接受传入的JSON作为JObject类型(来自Newtonsoft JSON库),然后通过将其设置为动态类型,可以通过点表示法访问属性。

1
2
3
4
public void Post([FromBody]JObject _json)
{
    dynamic json = _json;
}

试试下面的代码:

1
2
3
4
5
6
7
8
9
[Route("/test")]
[HttpPost]
public async Task Test()
{
   using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
   {
      var textFromBody = await reader.ReadToEndAsync();                    
   }            
}