我发现这是一个非常奇怪的问题。当我向我的web api服务发送xml请求时,每个反序列化都很好。但是,当我发送json请求时,此ONE属性不会反序列化。以下是对象:
[Serializable]
[DataContract(Namespace = "")]
public class TransactionData
{
// bunch of other properties that are unaffected ...
private GeotagInfo _geotag;
[DataMember(IsRequired = false, Name = "GeotagInfo", Order = 7)]
public GeotagInfo GeotagInfo
{
get { return _geotag ?? new GeotagInfo(); }
set { _geotag = value; }
}
}
[DataContract(Namespace = "")]
public class GeotagInfo
{
[DataMember(IsRequired = false, Name = "Longitude", Order = 1, EmitDefaultValue = false)]
public string Longitude { get; set; }
[DataMember(IsRequired = false, Name = "Latitude", Order = 2, EmitDefaultValue = false)]
public string Latitude { get; set; }
[Image(Nullable = true)]
[DataMember(IsRequired = false, Name = "MapImage", Order = 3, EmitDefaultValue = false)]
public string MapImage { get; set; }
[XmlIgnore]
public int TransactionId { get; set; }
}
当使用xml请求在控制器的入口点中断时。地理标记属性在那里并且已经完全填充。当我对json请求执行相同操作时,将实例化地理标记属性,但其所有值都为null。这个父对象中的其他所有内容都很好。
这是json请求中的属性:
"GeotagInfo": {
"Longitude": "-yy.yyyy",
"Latitude": "xx.xxxx",
"MapImage": "base64 string"
}
注意属性getter get { return _geotag ?? new GeotagInfo(); }
xml请求没有问题。但是,如果我删除它并将其get { return _geotag; }
,那么问题就会消失。不幸的是,这会导致其他问题深入到服务中。
这里发生了什么?如何使用xml而不是json(除非我删除默认的getter)。我知道MVC4使用json.net,所以这可能与它有关。
注意:正如其他线程中所建议的那样,我尝试从类中删除可序列化属性。没有变化。
答案 0 :(得分:2)
显然,Json.net序列化程序的操作顺序肯定存在差异。我想知道它是否试图对性能做一些懒惰的反序列化。无论如何,我写的一个错误揭示了序列化器的不同之处:
get { return _geotag ?? new GeotagInfo(); }
这永远不会设置私有字段。它应该是:
get { return _geotag ?? (_geotag = new GeotagInfo()); }
所以我的假设是私有字段永远不会被设置,这就是让我觉得它被设置为本身延迟加载反序列化的原因。所以现在我们已经过了反序列化过程,在私有字段上执行的检查将始终返回null,因此默认返回一个空对象。
答案 1 :(得分:1)
解决方法是创建两个属性,一个用于序列化,另一个用于进一步使用:
[Serializable]
[DataContract(Namespace = "")]
public class TransactionData
{
// bunch of other properties that are unaffected ...
private GeotagInfo _geotag;
[DataMember(IsRequired = false, Name = "GeotagInfo", Order = 7)]
public DataMember_GeotagInfo GeotagInfo
{
get;
set;
}
public GeotagInfo GeotagInfo
{
get { return DataMember_GeotagInfo ?? new GeotagInfo(); }
set { DataMember_GeotagInfo = value; }
}
}