7

我正在将 PUT 请求中的 json 有效负载发送到 Web API 控制器操作。有问题的操作具有如下所示的签名:

public IHttpActionResult Post([FromBody]SaveThingRequest request)

SaveThingRequest 看起来像这样:

public class SaveThingRequest
{
    public List<ElementInfo> Elements { get; set; }

    public class ElementInfo
    {
        public List<ElementSettingInfo> Settings { get; set; }

        public class ElementSettingInfo
        {
            public string Name { get; set; }
            public string Value { get; set; }
        }
    }
}

我在包含具有设置的元素的请求正文中发布 json。我已经通过在控制器操作中手动反序列化并确认 JSON 具有类似于以下内容的结构来确认这一点:

{
    Elements: [
        {
            Settings: [
                {
                    Name: 'Name 1',
                    Value: 'Value 1'
                },
                {
                    Name: 'Name 2',
                    Value: 'Value 2'
                }
            ]
        },
        {
            Settings: [
                {
                    Name: 'Name 1',
                    Value: 'Value 1'
                },
                {
                    Name: 'Name 2',
                    Value: 'Value 2'
                }
            ]
        }
    ]
}

但是,当 .NET 反序列化有效负载并创建 SaveThingRequest 时,我的元素已填充,但它们都具有 null 设置属性。我不知道如何解决这个问题。有人对这里可能发生的事情有任何想法吗?

4

5 回答 5

22

这个问题应该删除。它像宣传的那样工作。我的问题是我在 JSON 上有一个名为“设置”(小写)的附加属性,反序列化程序试图匹配该属性,因为如果未找到区分大小写的匹配,NewtonSoft 反序列化会尝试不区分大小写的匹配。我能够通过将方法的签名更改为:

public IHttpActionResult Post([FromBody]object request)

然后将其添加到方法实现中:

var result = JsonConvert.DeserializeObject<SaveThingRequest>(request.ToString());

我得到一个反序列化异常说:

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“System.Collections.Generic.List`1[Noteable.Contracts.ClinicalReports.SaveThingRequest+ElementInfo+ElementSettingInfo]”,因为该类型需要 JSON数组(例如 [1,2,3])正确反序列化。要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3])或更改反序列化类型,使其成为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像这样的集合类型可以从 JSON 对象反序列化的数组或列表。JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。路径 'Elements[0].settings.TextSize',第 11 行,位置 20。

消息的结尾向我展示了反序列化器失败时正在反序列化的内容,并为我指明了正确的方向。=[

于 2014-08-14T18:02:42.900 回答
5

我陷入了同样的问题。然而,问题是别的。

在我的例子中,没有被序列化的属性是在没有公共访问说明符的情况下声明的。我向公众宣布了它,它运行得非常好。

希望这会帮助陷入这种情况的人。我花了 20 分钟才达到这个解决方案。

于 2017-01-16T15:46:07.510 回答
0

确保您没有像我那样做一些愚蠢的事情,而是从浏览器发送了一个部分“字符串化”的 JSON 字符串而不是 JSON 对象。

看到问题了吗?起初我没有,直到我尝试从字符串反序列化它,然后我意识到它shippingAddress本身是一个字符串,而不是一个实际的 JSON 对象。对象的其余部分是正确的 JSON,但我不小心序列化了 shippingAddress 字段。

{ "fspID": 571285, "foo": 444, "shippingAddress": "{\"countryCode\":\"US\",\"firstName\":\"Test User\",\"lastName\": null,\"address1\":\"1 Main St4\",\"address2\":null,\"company\":null,\"city\":\"San Jose\",\"stateOrProvince\" :\"California\",\"stateCd\":\"CA\",\"zipOrPostal\":\"95131\",\"countryName\":\"United States\",\"countryDesc\": \"美国\",\"电话\":null,\"phone2\":null}" }

于 2015-10-26T22:45:20.543 回答
0

如果您使用 JSON.NET 和属性[JsonProperty]来命名属性 - 请确保您没有意外复制粘贴相同的属性两次并忘记更新字符串值。

 [JsonProperty("billingAddress")]
 public Address BillingAddress { get;set; }

 [JsonProperty("billingAddress")]
 public Address ShippingAddress { get;set; }

这会抛出一个Newtonsoft.Json.JsonSerializationException你实际上看不到的东西,并且会搞砸模型。

于 2015-10-27T09:15:55.937 回答
0

我遇到了同样的问题,即子属性为空。然而问题是别的。

我在该属性上只有一个 getter,一旦我也添加了一个 setter,那么该属性就会按预期设置。

于 2021-08-26T09:26:47.820 回答