我从外部服务接收JSON,并且说JSON可以使用与C#命名规则不兼容的字段名称。如
"$" : {//object definition here}
我无法将我的课程命名为单个“$”。我正在使用System.Runtime.Serialization数据注释来指定一个字段,从中反序列化这个奇怪命名的对象:
[DataMember(Name = "$")]
public Item Info { get; set; }
反序列化有效,但现在我想更好地格式化它,以便它不会再次序列化回"$" : {//object definition here}
。有没有办法我可以指定一个序列化规则,说明这个字段需要使用属性名Info
进行序列化,同时仍然从名为$
的成员反序列化?我希望我的服务用户看到的是:
"Info" : {//object definition here}
答案 0 :(得分:3)
执行此操作的一种方法是使用自定义IContractResolver
,它基本上告诉Json.Net忽略您的属性名称注释。在反序列化时,您让Json.Net正常工作,因此使用注释。在序列化时,将解析器添加到序列化程序设置,这会导致Json.Net使用您的类属性名称而不是带注释的名称。
以下是解析器所需的代码:
class OriginalNameContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
// Get the JsonProperties (with annotated names) from the base class
IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
// For each property, replace the annotated name with the real name
foreach (JsonProperty prop in list)
{
prop.PropertyName = prop.UnderlyingName;
}
return list;
}
}
以下是演示如何运作的演示:
class Program
{
static void Main(string[] args)
{
string json = @"{ ""$"" : { ""$moniker"" : ""blob sprocket"" } }";
Foo foo = JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine("name from JSON = " + foo.Info.Name);
Console.WriteLine();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new OriginalNameContractResolver();
settings.Formatting = Formatting.Indented;
json = JsonConvert.SerializeObject(foo, settings);
Console.WriteLine(json);
}
}
class Foo
{
[JsonProperty("$")]
public Item Info { get; set; }
}
class Item
{
[JsonProperty("$moniker")]
public string Name { get; set; }
}
输出:
name from JSON = blob sprocket
{
"Info": {
"Name": "blob sprocket"
}
}