代码之家  ›  专栏  ›  技术社区  ›  Dan Cundy

API控制器无法从POST body读取Json

  •  0
  • Dan Cundy  · 技术社区  · 5 年前

    背景

    我在我的身体发送JSON到我的API控制器,但不断得到以下错误。

    {“:[”分析值时遇到意外字符:{。路径

    我的HTTP请求

    HttpClient client = new HttpClient();
    HttpRequest httpRequest;
    HttpResponseMessage httpResponse = null;
    httpRequest = new HttpRequest("", HostnameTb.Text, null);
    
    var values = new Dictionary<string, string>
    {
        { "APIKey", APIKeyTb.Text }
    };
    
    string json = JsonConvert.SerializeObject(values);
    StringContent content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
    httpResponse = client.PostAsync(HostnameTb.Text, content).Result;
    
    var responseString = await httpResponse.Content.ReadAsStringAsync();
    

    我的控制器看起来像这样。

    [HttpPost]
    public void Post([FromBody] string value)
    {
      //Never gets here.
    }
    

    正文中的Json。

    问题

    我更喜欢使用.Net内核 [From Body] 功能,而不是手动获取内容。

    我希望JSON字符串在字符串中可用 Value 参数

    我错过了什么?

    2 回复  |  直到 5 年前
        1
  •  7
  •   Tomas Aschan    5 年前

    ASP.NET核心尝试反序列化 {"APIKey":"1283f0f8..."} string 值,并失败,因为它希望输入是有效的JSON字符串。

    换句话说,如果你的身体 "{\"APIKey\":\"1283f0f8...\"}" 正如您所期望的那样,输入变量中将包含JSON字符串。

    APIKey 值而不更改HTTP请求,创建输入类型:

    public class Input
    {
        public string ApiKey { get; set; }
    }
    

    并将其用作控制器操作的输入:

    [HttpPost]
    public void Post([FromBody] Input input)
    {
        var apiKey = input.ApiKey;
        // etc
    }
    

    或者,更改您的HTTP请求以发送 一串 :

    // ...
    var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
    // ...
    

    注意使用 JsonConvert.SerializeObject() 而不是 ToString() "foo".ToString() 仍然只是 "foo" ,当你想的时候 "\"foo\""

        2
  •  2
  •   Chris Pratt    5 年前

    不是这样的。 [FromBody] 调用序列化程序来反序列化请求体。然后,modelbinder尝试将其绑定到param。在这里,它不能这样做,因为您绑定到一个字符串,而请求主体是一个字典。本质上,引擎盖下发生的事情(伪代码)是:

    value = JsonConvert.DeserializeObject<string>(dictionaryAsJson);
    

    您将从JSON.NET获得反序列化错误,因为它无法将JSON解析为字符串。

    如果您想将值作为字符串,那么应该将其作为 text/plain application/json . 否则,您将需要绑定到一个实际表示传入的JSON对象的类型,这将是一个 Dictionary<string, string>

        3
  •  0
  •   b.sodhi    4 年前

    我对ASP.NET Core 3.1也有同样的问题。我在我的API控制器上发布了一个JSON,看起来像:

    public JsonResult Save([FromBody]MainDetails obj){ ... }
    

    我的问题是 ChildDetails.StartDate 我的 MainDetails DateTime ,我发了一封 null JSON中的值。这导致反序列化在控制器上失败。我将属性类型更改为 DateTime? 从…起 日期时间 让它工作。

    无效的 希望这有帮助。