【问题标题】:JSON.NET Deserialization Property Name conversion to ExpandoObject with custom ContractResolver使用自定义 ContractResolver 将 JSON.NET 反序列化属性名称转换为 ExpandoObject
【发布时间】:2013-12-29 21:05:13
【问题描述】:

我有这个 JSON:

{"firstName": "John","lastName": "Doe"}

这个 JSON.NET 合约解析器:

public class CustomContractResolver : DefaultContractResolver{      
  protected override string ResolvePropertyName(string propertyName)
  {
    return propertyName.Replace("_",""); 
  }
}

我有这个 WebApi 控制器方法,它使用扩展来使用提供的字段对数据库行进行部分更新:

public virtual int Post(int id, JObject content)
{
  var obj = JsonConvert.DeserializeObject<ExpandoObject>(content.ToString(), new JsonSerializerSettings { ContractResolver = new CustomContractResolver() });
  db.Update<Person>(id, obj)
}

我希望反序列化的 expando 具有属性 first_namelast_name 以匹配我的模型/数据库列名,但它的属性仍然与 JSON 匹配。直接反序列化到 Person 具有 first_namelast_name 作品,如 L.B.帮助我在下面发现,但我的 db 层需要一个 Expando 用于部分记录更新,否则它将吹走 Person 的任何属性,这些属性未由 json 指定,因此模型中的 null 没有指定。

我可以在 ContractResolver 中做什么来转换 Expando 的属性?

【问题讨论】:

  • 您确定您的数据库层期望完全扩展,也许是IDictionary&lt;string,object&gt;
  • 是的,对t == typeof(ExpandoObject) 进行了显式检查,之后它从Expando 转换为IDictionary&lt;string,object&gt; 动态构建列列表。

标签: c# json asp.net-web-api json.net deserialization


【解决方案1】:

你可以在反序列化时使用这个 ContractResolver

var obj = JsonConvert.DeserializeObject<Person>(
            json, 
            new JsonSerializerSettings { 
                    ContractResolver = new CustomContractResolver() 
            });

public class CustomContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        return propertyName.Replace("_",""); 
    }
}

【讨论】:

  • 是的,这正是我在问题的代码中所做的(除了我的解析器是camelCasing 属性名称),但对象的字段没有改变。
  • @ThePants 我在发布之前对其进行了测试,它可以工作。这是 Person 类 public class Person { public string first_name { get; set; } public string last_name { get; set; } } 这是 json {"firstName": "John","lastName": "Doe"}
  • @ThePants BTW:请注意,我反序列化为 Person 类而不是 ExpandoObject
  • 是的,我刚刚注意到并尝试了一下。当我反序列化为 Person 而不是 Expando 时,它确实有效。为什么它不适用于 Expandos?我的数据库层想要一个 Expando 来做部分记录更新。
  • 好的,我想我明白了问题的根源。 ResolvePropertyName 方法始终在 Model -> Json 的相同方向上工作......这就是为什么我原来的 Resolver 不起作用......这也解释了为什么 Expandos 不起作用,因为它们没有任何 PropertyNames解决。不过,我仍然不知道如何编写一个可以真正与他们一起工作的 ContractResolver。
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 2023-04-07
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
相关资源
最近更新 更多