【问题标题】:Serializing with Json.NET: how to require a property not being null?使用 Json.NET 进行序列化:如何要求属性不为空?
【发布时间】:2017-03-15 11:23:07
【问题描述】:

使用 Newtonsoft 的 Json.NET 序列化程序,是否可以要求属性包含非空值并在序列化时抛出异常,如果不是这种情况?比如:

public class Foo
{
    [JsonProperty("bar", SerializationRequired = SerializationRequired.DisallowNull)]
    public string Bar { get; set; }
}

我知道可以在反序列化时执行此操作(使用 JsonPropertyRequired 属性),但我找不到任何用于序列化的内容。

【问题讨论】:

标签: c# json serialization json.net


【解决方案1】:

现在可以通过将JsonPropertyAttribute 设置为Required.Always

这需要 Newtonsoft 12.0.1+,在提出这个问题时它还不存在。

下面的示例抛出一个JsonSerializationException(“必需的属性'Value'需要一个值但得到了null。路径'',第1行,位置16。”):

void Main()
{
    string json = @"{'Value': null }";
    Demo res = JsonConvert.DeserializeObject<Demo>(json);
}

class Demo
{
    [JsonProperty(Required = Required.Always)]
    public string Value { get; set;}
}

【讨论】:

  • 问题是关于序列化,而不是反序列化。
  • @Stmated: Required.Always 适用于两者。 JsonConvert.SerializeObject(new Demo()); 也会抛出 JsonSerializationException(具体来说,Cannot write a null value for property 'Value')。
  • 我今天用 13.0.1 试过这个,但是没有用。好吧,除非它是一种功能错误,如果 NullValueHandling 设置为忽略,则验证未完成。这是给我的。在这种情况下,这是一个交易破坏者。编辑:是的。情况就是这样。所以你是对的,但这不是一个好的实现。
  • @Stmated:如果您告诉 Newtonsoft 忽略 NullValueHandling,您为什么希望验证空值?
  • 因为我希望即使序列化格式在输出中跳过空值,也能遵守合同。它实际上仍然是 null,只是不是可见的 null。
【解决方案2】:

Newtonsoft serialization error handling documentation 之后,您可以在 OnError() 方法中处理 null 属性。我不完全确定您会将什么作为 NullValueHandling 参数传递给 SerializeObject()。

public class Foo
{
     [JsonProperty]
     public string Bar 
     {
         get 
         {
             if(Bar == null)
             {
                 throw new Exception("Bar is null");
             }
             return Bar;
         }
         set { Bar = value;}

     [OnError]
     internal void OnError(StreamingContext context, ErrorContext errorContext)
     {
          // specify that the error has been handled
          errorContext.Handled = true;
          // handle here, throw an exception or ...
     }
}


int main()
{
     JsonConvert.SerializeObject(new Foo(), 
                        Newtonsoft.Json.Formatting.None, 
                        new JsonSerializerSettings { 
                            NullValueHandling = NullValueHandling.Ignore
                        });
}

【讨论】:

  • 哈!这会起作用,但要让事情发生需要大量的管道......我宁愿编写自己的验证器/验证属性并在序列化之前调用它!
猜你喜欢
  • 2014-09-28
  • 2020-06-08
  • 2022-01-19
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
相关资源
最近更新 更多