FromBody 字符串参数为空

FromBody string parameter is giving null

这可能是非常基本的东西,但我无法弄清楚我哪里出错了。

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

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

也许这是我对邮递员做的不正确的事情,但我一直在尝试在正文的值部分使用“=test”(如在其他有关此主题的问题中所见)-x-www- form-url 编码部分,键为 jsonString,什么都没有。我也尝试过使用 raw - text 和 raw - text/plain。我得到了 id,所以我知道 url 是正确的。对此的任何帮助将不胜感激。

PostMan 目前是这样设置的:

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

通过使用 [FromBody] 声明 jsonString 参数,您告诉 ASP.NET Core 使用输入格式化程序将提供的 JSON(或 XML)绑定到模型。因此,如果您提供一个简单的模型 class

,您的测试应该有效
public class MyModel
{
    public string Key {get; set;}
}

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

并发送了一个 JSON 赞

{
    key: "value"
}

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

访问表单数据

我个人更喜欢模型绑定,因为类型安全。

你走在正确的轨道上。

在你的 header 集上

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

POST 请求的 body 应该是 =test 而不是别的。对于 unknown/variable 字符串,您必须 URL 对值进行编码,这样您就不会意外地使用输入字符进行转义。


另见 POST string to ASP.NET Web Api application - returns null

引用 Parameter Binding in 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:

[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.

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 编码的请求将如下所示

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] 属性时,发送的字符串不应是原始字符串,而是 JSON 字符串,因为它包含引号:

"test"

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

相似答案

我知道这个答案有点老了,有一些很好的答案已经解决了这个问题。为了扩大这个问题,我想再提一件在过去 4 或 5 小时内让我发疯的事情。

非常非常非常重要的是,您的模型 class 中的属性启用了 set 属性。

这个不会工作(参数仍然为空):

/* 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;}
}

工作:

/* 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.stringify(bodyStuff).

经过 1 小时的努力,终于成功了。

这将消除 null 问题,还以通用方式获取 JSON key1value1 值(无模型绑定),.

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

Postman (looks exactly, like below):

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

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

ValuesController.cs

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;
}

目前一切正常,不确定如果我有子键是否需要模型绑定到 class,或者子键上的 DeserializeObject 可能会起作用。

在摆弄 Google 并在 Stack Overflow 中尝试错误代码的漫长噩梦之后,我发现将 ([FromBody] 字符串模型) 更改为 ([FromBody] 对象模型) 确实很神奇,但我不是使用 .NET 4.0 是的是的我知道它很旧但是......

Post原始字符串JSON,不要忘记双引号!

试试下面的代码:

[Route("/test")]
[HttpPost]
public async Task Test()
{
   using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
   {
      var textFromBody = await reader.ReadToEndAsync();                    
   }            
}

如果您不 want/need 绑定到具体的 class,您可以将 JSON 直接传递给 WebAPI 控制器。控制器能够通过使用 ExpandoObject 类型来接受 JSON。这是方法示例:

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

Content-Typeheader设置为application/json并发送JSON 作为 body。 keyValuePairs object 将包含 JSON key/value 对。

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

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

对于 .net 核心 3.1 post(url, JSON.stringify(yourVariable) ) 像魅力一样工作 在控制器 MyMethod([FromBody] string yourVariable)

我刚刚 运行 对此感到沮丧。我的设置: header 设置为 Content-Type: application/JSON 并以 JSON 格式传递来自 body 的信息,并正在阅读 [FromBody]控制器。

一切设置都很好,我希望它能正常工作,但问题出在发送过来的 JSON 上。由于它是一个复杂的结构,我的 类 之一被定义为 'Abstract' 没有得到初始化,因此值没有正确分配给模型。我删除了 abstract 关键字,它就起作用了..!!!

一个提示,我可以解决这个问题的方法是将部分数据发送到我的控制器并检查它何时变为空...因为它是一个复杂的模型,我一次将一个模型附加到我的请求中参数。希望它能帮助遇到这个愚蠢问题的人。

我花了一整天时间来解决类似的问题。

您必须知道内置序列化器和 Newtonsoft 的工作方式不同。 我的案例内置无法将 JSON 数字解析为 System.String。 但我没有明显的异常或细节,只是数据为空。

我是在这样记录 ModelState 时才发现的:

logger.LogInformation($"ModelState = {ModelState.IsValid}");
string messages = string.Join("; ", ModelState.Values
                    .SelectMany(x => x.Errors)
                    .Select(x => x.ErrorMessage));
logger.LogInformation($"ModelMessages = {messages}");

然后我在日志中看到了特定的异常:

The JSON value could not be converted to System.String

作为修复,我做了:

  1. 安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson 这是预览版 版本。
  2. 改为services.AddControllers().AddNewtonsoftJson();

解决方案取自

此外,如果您使用的是 Postman“环境”,请确保在 运行 使用它的 API 脚本之前选择环境。否则,它将只发送变量字符串 -- {{varname}} -- 而不是它们的关联值,API 适当地拒绝了。

这或许也能派上用场。 我需要将 JSON 字符串传递给我的 API 控制器。但该模型是事先未知的。使用 JObject 作为对象类型效果很好。 您可以稍后序列化以获取字符串。

[FromBody] JObject unknownStringJsonObject

您可以只使用“对象”而不是像这样的字符串:

public async Task<IActionResult> Method([FromBody] Object plainJson)

然后打印对象:

Console.WriteLine(plainJson.ToString());

就是这样!