FromBody字符串参数为null

时间:2016-11-28 20:48:05

标签: c# asp.net-web-api asp.net-web-api2 postman asp.net-web-api-routing

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

我试图从POST的主体中获取一个字符串,但“jsonString”只显示为null。我也想避免使用模型,但也许这是不可能的。我用PostMan打的那段代码就是这个块:

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

也许这是我对邮递员做错的事情,但我一直试图在身体的价值部分使用“= test”(如在关于这个主题的其他问题中看到的那样) - x-www-form- urlencoded节,键为jsonString,没什么。我也尝试过使用raw-text和raw-text / plain。我得到了身份证,所以我知道网址是正确的。任何有关这方面的帮助将不胜感激。

PostMan目前设置如下:

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

15 个答案:

答案 0 :(得分:36)

引用Parameter Binding in ASP.NET Web API

  

使用[FromBody]

     

要强制Web API从请求正文中读取简单类型,请添加    [FromBody] 属性参数:

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

在此示例中,Web API将使用媒体类型格式化程序来读取   来自请求正文的 jsonString 的值。这是一个示例客户端   请求。

     
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"
     

当参数具有[FromBody]时,Web API使用Content-Type标头   选择格式化程序。在此示例中,内容类型为   “application / json”和请求体是一个原始的JSON字符串(不是   JSON对象)。

在上面的例子中,如果数据在正文中以正确的格式提供,则不需要任何模型。

对于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

答案 1 :(得分:32)

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

,那么您的测试应该可行
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访问表单数据。

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

答案 2 :(得分:12)

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

"test"

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

类似的回答string value is Empty when using FromBody in asp.net web api

答案 3 :(得分:6)

你走在正确的轨道上。

在标题集上

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

POST请求的正文应该是=test而不是其他内容。对于未知/变量字符串,您必须对值进行URL编码,以便您不会意外地使用输入字符进行转义。

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

答案 4 :(得分:3)

在我的情况下,我忘了使用     JSON.stringify(bodyStuff)。

答案 5 :(得分:2)

我知道这个答案有点陈旧,有一些非常好的答案已经解决了问题。

为了扩大这个问题,我想提一下让我在过去4或5个小时内疯狂的事情。


非常非常重要的是,您的模型类中的属性启用了 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;}
}

WILL 工作:

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

答案 6 :(得分:2)

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

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库),然后将其设置为 dynamic 类型,则可以访问点符号表示属性。

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

答案 7 :(得分:1)

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

enter image description here

答案 8 :(得分:1)

尝试以下代码:

    return this.http.get('https://someUrl/getall', { headers: headers, observe: 'response' }).pipe(
      map((response: any) => {
        return response;
      }),
    );

答案 9 :(得分:0)

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

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

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

  

邮递员(看起来完全像下面一样):

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

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

对于.net core 3.1帖子(URL, JSON.stringify (yourVariable)),它的作用就像魅力 在控制器MyMethod([FromBody]字符串yourVariable)上

答案 12 :(得分:0)

我只是碰到这个而感到沮丧。我的设置:标头设置为Content-Type:application / JSON,并以JSON格式从正文传递信息,并在控制器上读取[FromBody]。

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

一个技巧,我想出的办法是将数据部分发送到我的控制器,并检查它何时为空...因为这是一个复杂的模型,所以我一次将一个模型追加到我的请求参数中。希望它能帮助遇到这个愚蠢问题的人。

答案 13 :(得分:0)

我整天都无法解决类似的问题。

您必须知道内置的serializor和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();

溶液取自https://stackoverflow.com/a/57652537/4871693

答案 14 :(得分:0)

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