当前位置: 首页 > 知识库问答 >
问题:

如何将缺少的属性反序列化为Json中的默认值。网络?

裴俊豪
2023-03-14

我有一个类,它用Data合同和Data会员属性进行了注释。一些成员被标记为Data会员(Is必备=true)。当我通过Json的线路序列化实例时。NET,并且所需的html" target="_blank">对象成员具有空值,然后它们的序列化值在输出中丢失(这显然相当于在JSON中为空)。我没意见。

我创建了一种“echo”服务,它返回作为响应发送给它的数据。因此,此服务接收缺少成员的JSON(或空成员,具体取决于您如何看待它),然后将其发送回我的JSON。NET客户端。通过Fiddler(代理嗅探器)查看,线路上的JSON在两个方向上看起来都一样。到现在为止,一直都还不错。

当原始Json。NET发送方收到JSON响应以对其进行反序列化,序列化程序引发一个关于在JSON负载中找不到所需成员的异常:

Required property 'IAmRequired' not found in JSON. Path ''.

这是不幸的,因为序列化程序因此无法对以前序列化的数据进行反序列化,而不会出现问题。

除了更改Data合同类以使成员不需要(出于多种原因我不想这样做),是否有办法使Json. NET将缺少的成员反序列化为默认值,例如null?

以下是我的反序列化代码:

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
}

共有2个答案

贺博厚
2023-03-14

这看起来像是我的代码上的一个真正的缺点,需要对每个可为null但必需的成员重复,但它可以工作,而且似乎会增加微不足道的开销。我在原始代码片段中的try块之前添加了以下内容:

JToken maybeHasIt = null;
if (!json.TryGetValue("IAmRequired", StringComparison.InvariantCultureIgnoreCase, out maybeHasIt))
{
    json.Add("IAmRequired", null);
}
潘振国
2023-03-14

如果您有标记为[数据成员(必需=true)]的属性,并且您想要覆盖所需的行为,那么您可以做以下几件事:

>

  • 您可以使用[JsonProperty(Required=Required.Default)]标记这些相同的属性。这是因为在Json中,JsonProperty的优先级高于DataMember。网

    [DataContract]
    public class HasRequired
    {
        [DataMember(Required = true)]
        [JsonProperty(Required = Required.Default)]
        public string IAmRequired { get; set; }
    }
    

    或者,您可以创建一个自定义ComptResolver,以编程方式设置必需=必需。每个属性的默认

    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();
    

  •  类似资料:
    • 我使用的是Json。net将对象序列化到数据库。 我向类中添加了一个新属性(该属性在数据库的json中缺失),我希望新属性在json中缺失时具有默认值。 我尝试了DefaultValue属性,但它不起作用。我正在使用私有setter和构造函数来反序列化json,因此在构造函数中设置属性的值将不起作用,因为有一个带有该值的参数。 以下是一个例子: 我预计年龄是5岁,但现在是零岁。 有什么建议吗?

    • 我尝试使用以下代码反序列化API中接收的JSON对象: 我的类使用Lombok生成构造函数、getter和setter,如下所示: 这两个属性都应该是可选的,如果没有提供,则使用类定义中指定的默认值。但是,如果我现在尝试反序列化JSON 字段为。根据我的理解,以及我找到的所有示例代码,应该是一个空列表。 编辑:不是重复的,因为我使用的是没有选项的Lombok

    • 问题内容: 使用Jackson 2,我正在寻找一种 通用的 方式将对象序列化为单个值(然后序列化它们,然后再填充该单个字段),而不必重复创建JsonSerializer / JsonDeserializer来处理每种情况。@JsonIdentityInfo批注非常接近,但由于我知道,它将始终对完整的子对象进行序列化,因此略微遗漏了该标记。 这是我想做的一个例子。给定的类: 我希望Order可以序列

    • 问题内容: 我在play scala中具有以下模型的等效项: 对于以下Foo实例 我将获得以下JSON文档: 该JSON将持久保存并从数据存储中读取。现在,我的要求已更改,我需要向Foo添加一个属性。该属性具有默认值: 写入JSON没问题: 但是,从中读取会由于缺少“ / status”路径而产生JsError。 如何提供具有最小噪声的默认设置? (ps:我有一个答案,我将在下面发布,但我对此并不

    • 我的JSON字符串是: 我想要实现的是,当JSON中没有提供schemaVersion时,能够在默认情况下反序列化到SubClassV1,但即使在Superclass中将schemaVersion初始化为“1.0”时,我仍然会收到以下错误:

    • 我正在尝试使用Gson反序列化格式为“2018-05-27”的json中的date属性。在反序列化之后,我希望日期为LocalDate格式。 对于json输入: {"id": 1,"name":"test","start Date":"2018-01-01","endDate":"2018-01-05",} 我收到startDate和endDate的错误: Java语言lang.IllegalSt