Zoo*_*Way 11 c# arrays serialization json json.net
我使用Newtonsoft JSON来序列化/反序列化我的对象.其中一个包含一个带有受保护的setter的数组,因为构造函数构建了数组本身,只有成员被操纵.
这可以没有问题地序列化,但是当涉及反序列化时,它被忽略,因为它不是公共的.我尝试了一个自定义转换器,它也没有被调用,因为它不公开.
这是一个最小化的例子:
public static class TestCoordsDeserialization
{
private class Coords
{
public Double X { get; set; }
public Double Y { get; set; }
public Double Z { get; set; }
public Double A { get; set; }
}
private class Engine
{
public string Text { get; set; }
public int Id { get; set; }
public Coords[] Outs { get; protected set; }
public Engine()
{
this.Outs = new Coords[3];
for (int i = 0; i < this.Outs.Length; i++)
{
this.Outs[i] = new Coords();
}
}
}
public static void Test()
{
Engine e = new Engine();
e.Id = 42;
e.Text = "MyText";
e.Outs[0] = new Coords() { A = 0, X = 10, Y = 11, Z = 0 };
e.Outs[1] = new Coords() { A = 0, X = 20, Y = 22, Z = 0 };
e.Outs[2] = new Coords() { A = 0, X = 30, Y = 33, Z = 0 };
string json = JsonConvert.SerializeObject(e);
Console.WriteLine(json); //{"Text":"MyText","Id":42,"Positions":{"Test":9,"Outs":[{"X":10.0,"Y":11.0,"Z":0.0,"A":0.0},{"X":20.0,"Y":22.0,"Z":0.0,"A":0.0},{"X":30.0,"Y":33.0,"Z":0.0,"A":0.0}]}}
Engine r = JsonConvert.DeserializeObject<Engine>(json);
double value = r.Outs[1].X; // should be '20.0'
Console.WriteLine(value);
Debugger.Break();
}
}
Run Code Online (Sandbox Code Playgroud)
我怎么能value成为20.0?
dbc*_*dbc 17
标记Outs与[JsonProperty]属性:
private class Engine
{
public string Text { get; set; }
public int Id { get; set; }
[JsonProperty] // Causes the protected setter to be called on deserialization.
public Coords[] Outs { get; protected set; }
public Engine()
{
this.Outs = new Coords[3];
for (int i = 0; i < this.Outs.Length; i++)
{
this.Outs[i] = new Coords();
}
}
}
Run Code Online (Sandbox Code Playgroud)
尝试这个:
var contractResolver = new DefaultContractResolver();
contractResolver.DefaultMembersSearchFlags |= BindingFlags.NonPublic;
Engine r = JsonConvert.DeserializeObject<Engine>(json), new JsonSerializerSettings
{
ContractResolver = contractResolver
});
Run Code Online (Sandbox Code Playgroud)
使用上述代码,您将收到以下警告消息:
“DefaultContractResolver.DefaultMembersSearchFlags”已过时:“DefaultMembersSearchFlags”已过时。要修改从 DefaultContractResolver 继承的序列化成员,并重写 GetSerializedMembers 方法。
要解决它,您可以使用以下解决方案:
创建一个继承自的类DefaultContractResolver以获取非公共属性:
public class CustomContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(
MemberInfo member,
MemberSerialization memberSerialization)
{
var prop = base.CreateProperty(member, memberSerialization);
if (!prop.Writable)
{
var property = member as PropertyInfo;
if (property != null)
{
var hasNonPublicSetter = property.GetSetMethod(true) != null;
prop.Writable = hasNonPublicSetter;
}
}
return prop;
}
}
Run Code Online (Sandbox Code Playgroud)
最后使用它如下:
var contractResolver = new CustomContractResolver();
Engine r = JsonConvert.DeserializeObject<Engine>(json), new JsonSerializerSettings
{
ContractResolver = contractResolver
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2714 次 |
| 最近记录: |