【问题标题】:Deserializing with Json.NET: Requiring a property/key to be present使用 Json.NET 反序列化:需要存在属性/键
【发布时间】:2013-04-30 04:08:39
【问题描述】:

当使用Json.NET 将 JSON 字符串反序列化为对象时,如何要求 JSON 搅拌中存在键/属性,但允许 NULL 值?

例如:

假设我有一个类/对象...

[DataContract]
public class Car
{
    [DataMember(IsRequired = true)]
    public string Vin {get; set;}

    [DataMember(IsRequired = true)]
    public string Color {get; set;}

    public string Description {get; ;set}
}

在上面的示例中,VIN 和 Color 是必需的,如果 JSON 字符串中缺少其中任何一个,则会引发异常。但是可以说,Description 属性在反序列化后是否具有值是可选的。换句话说,NULL 是一个有效值。有两种方法可以在 JSON 字符串中实现这一点:

1)

{
    "vin": "blahblahblah7",
    "color": "blue",
    "description":  null
}

或 2)

{
    "vin": "blahblahblah7",
    "color": "blue"
}

问题是我不想仅仅因为 JSON 字符串中省略了键/值对就假设 Description 值应该为 NULL。我希望 JSON 的发件人明确将其设置为 NULL。如果发生场景 #2,我想检测它并以错误消息进行响应。那么如何要求键/值对存在,但接受 NULL 作为值?

如果有帮助,我会尝试在 ASP.NET Web API 项目的上下文中解决这个问题。

【问题讨论】:

  • [DataMember(IsRequired = true)] public string Description { get;放; } 不工作?提交的描述将需要,但可以接受空值
  • 这是在 Web 环境中还是基于 .NET 的纯桌面应用程序?

标签: c# .net json.net


【解决方案1】:

呃。我应该多花一点时间在 Json.NET 文档上...

答案是JsonPropertyAttributeRequired属性,它是enum类型Newtonsoft.Json.Required

[JsonProperty(Required = Newtonsoft.Json.Required.AllowNull)]
public string Description {get; set;}

【讨论】:

    【解决方案2】:

    这里真正的问题是:为什么要强制发送方在某些值上设置 null? 在构建应用程序时,您永远不能强迫用户行为,这是攻击您的应用程序的第一窗口。

    始终假设用户在某些时候不会做你想做的事。 如果该 JSON 来自您拥有的任何其他应用程序,只需将其发送为 null,如果它是外部应用程序或用户输入,则假设一切皆有可能。

    并且Required并不意味着该字段在输入中是必需的,它意味着它需要一个值。那是你的问题。

    【讨论】:

    • 我了解您所说的用户可能并不总是按照我的意愿行事。但是,坦率地说,这是我的 API。我定义它的规则。如果有人想使用它,他们会按照我的规则行事。我的目的是检测“必需”键/值对何时丢失,然后返回 400 告诉客户端它缺少描述(在这种情况下)。我也知道您对 [Required] 属性的意思是指 value 是必需的,而 not 是必需的键/值对.这就是我首先提出这个问题的原因。
    • 那种“Is My API”的想法不太好。我的意思是,用户必须发送 null 只是因为您无法解决问题? Jras 给了你答案,在你这边使用默认值。永远不要强迫人们遵守规则。
    • 我希望用户发送 null 因为我不想对他们正在尝试做的事情做出假设。根据我的经验,做出假设可能会导致问题。
    • 我真的不明白你是怎么想的。我的意思是,如果用户不发送一个字段,它是空的……至少对你来说。没有魔法球可以告诉你,唯一可以告诉你的是用户。
    • 也许这就是您的想法:您有一个带有描述的 Car 对象。用户发送没有描述的请求,如果您将其设置为 null,您将丢失该值。是这样吗?如果是这样,那就错了。您有一个 Car 对象,但您将收到的信息不需要映射到该对象。您可以只查看值并根据需要使用它们,而无需更新任何缺失值。
    【解决方案3】:

    【讨论】:

    • 适用于序列化,但是当默认情况下需要所有成员时反序列化呢? [DefaultValue(null)] 被忽略。 [JsonProperty(Required = Required.Default)] 有效但冗长。
    猜你喜欢
    • 2020-06-08
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 2011-01-16
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多