我有一个用DataContract和DataMember属性注释的类。有些成员被标记为DataMember(IsRequired = true)
。当我从Json.NET通过线路序列化实例,并且所需的对象成员具有null值时,它们的序列化值在输出中丢失(这显然相当于在JSON中为null)。我没关系。
我创造了一种" echo"返回作为响应发送给它的数据的服务。所以这个服务接收带有缺少成员的JSON(或者根据你看它的方式为null成员),然后将它发送回我的Json.NET客户端。通过Fiddler(代理嗅探器)查看,线路上的JSON在两个方向上看起来都相同。到目前为止一切都很好。
当原始Json.NET发送方收到JSON响应以对其进行反序列化时,序列化程序会抛出一个关于在JSON有效负载中找不到所需成员的异常:
Required property 'IAmRequired' not found in JSON. Path ''.
这很不幸,因为序列化程序无法反序列化之前已经序列化的数据而没有问题。
如果没有更改DataContract类以使该成员不是必需的(由于多种原因我不想这样做),有没有办法让Json.NET将缺少的成员反序列化为默认值,例如null? / p>
这是我的反序列化代码:
HasRequired h = null;
JObject json = response as JObject; // hand waving here
try
{
JsonSerializer ser = new JsonSerializer();
ser.MissingMemberHandling = MissingMemberHandling.Ignore; // doesn't seem to help
ser.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; // doesn't seem to help
ser.NullValueHandling = NullValueHandling.Include; // doesn't seem to help
h = json.ToObject<HasRequired>(ser);
}
catch (Exception ex)
{
// bummer, missing required members still
}
答案 0 :(得分:3)
如果您有标有[DataMember(Required = true)]
的属性,并且您想要覆盖所需的行为,那么您可以执行以下操作:
您可以使用[JsonProperty(Required = Required.Default)]
标记相同的属性。这是有效的,因为[JsonProperty]
优先于Json.Net中的[DataMember]
。
[DataContract]
public class HasRequired
{
[DataMember(Required = true)]
[JsonProperty(Required = Required.Default)]
public string IAmRequired { get; set; }
}
或者,您可以创建一个自定义的ContractResolver,以编程方式在每个属性上设置Required = Required.Default
。
class CustomResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
prop.Required = Required.Default;
return prop;
}
}
要使用解析程序,只需将序列化程序中的ContractResolver
属性设置为自定义解析程序的新实例:
JsonSerializer ser = new JsonSerializer();
ser = new CustomResolver();
答案 1 :(得分:0)
这看起来像是我的代码中的一个真正的疣,并且需要为每个可空的但必需的成员重复,但是它起作用,并且似乎增加了可忽略的开销。我在原始代码段中的try块之前添加了这个:
JToken maybeHasIt = null;
if (!json.TryGetValue("IAmRequired", StringComparison.InvariantCultureIgnoreCase, out maybeHasIt))
{
json.Add("IAmRequired", null);
}