【问题标题】:How to get HttpClient Json serializer to ignore null values如何让 HttpClient Json 序列化程序忽略空值
【发布时间】:2013-02-17 05:06:54
【问题描述】:

我目前正在使用一个控制台应用程序,我正在使用 HttpClient 与 Apache CouchDB 数据库进行交互。我正在使用这篇文章:http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

当我通过 PostAsJsonSync 序列化文档并将文档发送到我的数据库时,我想忽略我的类中的 null 属性,但我不确定如何:

public static HttpResponseMessage InsertDocument(object doc, string name, string db)
    {
      HttpResponseMessage result;
      if (String.IsNullOrWhiteSpace(name)) result = clientSetup().PostAsJsonAsync(db, doc).Result;
      else result = clientSetup().PutAsJsonAsync(db + String.Format("/{0}", name), doc).Result;
      return result;
    }

    static HttpClient clientSetup()
    {
      HttpClientHandler handler = new HttpClientHandler();
      handler.Credentials = new NetworkCredential("**************", "**************");
      HttpClient client = new HttpClient(handler);
      client.BaseAddress = new Uri("*********************");
      //needed as otherwise returns plain text
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
      return client;
    }

这是我要序列化的类....

class TestDocument
  {
    public string Schema { get; set; }
    public long Timestamp { get; set; }
    public int Count { get; set; }
    public string _rev { get; set; }
    public string _id { get; set; } - would like this to be ignored if null
  }

非常感谢任何帮助。

【问题讨论】:

  • 在幕后,您可能正在使用 Json.NET。 stackoverflow.com/questions/9819640/…
  • 知道如何引用它正在使用的序列化程序吗?
  • 在将文档放入 CouchDB 时看起来和我的问题一模一样

标签: c# .net json


【解决方案1】:

假设您使用 Json.NET 来序列化您的对象,您应该使用 JsonProperty 属性的 NullValueHandling 属性

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]

查看这个很棒的articleonline help 了解更多详情

【讨论】:

  • 这将完全忽略它,即使它以后不再为空
  • 对...相应地更改了答案,因为 JsonIgnore 确实是不序列化属性
  • 这看起来很有希望,但由于某种原因它仍然没有忽略空值,即使它应该忽略!
  • 它有效,这是我的错误 - 我会将其标记为正确答案,因为它涉及更改最少的代码。
  • 这篇文章很棒,但是如果它更深入地解释这种情况,您的回答会更有帮助。我发现 HellBricks 的回答更有帮助,因为这是解决我问题的答案。
【解决方案2】:

我不确定您是否可以使用 PutAsJsonAsync 来做到这一点,因为您现在拥有它。 Json.NET 可以做到这一点,如果你能够使用它,并且如果它有帮助,则存在一个 NuGet 包。如果您可以使用它,我会将InsertDocument 函数重写为如下所示:

public static HttpResponseMessage InsertDocument(object doc, string name, string db)
    {
      HttpResponseMessage result;
      string json = JsonConvert.SerializeObject(doc, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
      if (String.IsNullOrWhiteSpace(name)) result = clientSetup().PostAsync(db, new StringContent(json, null, "application/json")).Result;
      else result = clientSetup().PutAsync(db + String.Format("/{0}", name), new StringContent(json, null, "application/json")).Result;
      return result;
    }

【讨论】:

  • clientSetup().PostAsync(db, new StringContent(json, null, "application/json")).Result;
  • 我用它来让它工作,但是(正如我上面提到的)它仍然忽略这两种方法并发送空变量
  • 这行得通,但不幸的是,我将上面的内容标记为正确答案,因为它对我的代码所做的更改最少。
  • @JamesMundy 哇。连属性都不知道。从现在开始我会使用它!好电话。
【解决方案3】:

如果您要发送的所有类的所有属性都需要这种行为(正是这种情况导致我提出这个问题),我认为这会更简洁:

using ( HttpClient http = new HttpClient() )
{
    var formatter = new JsonMediaTypeFormatter();
    formatter.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;

    TestDocument value = new TestDocument();
    HttpContent content = new ObjectContent<TestDocument>( value, formatter );
    await http.PutAsync( url, content );
}

这样就不需要给你的类添加属性,你也不需要手动序列化所有的值。

【讨论】:

    【解决方案4】:

    使用 HttpClient.PostAsync

    JsonMediaTypeFormatter jsonFormat = new JsonMediaTypeFormatter();
    jsonFormat.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore;
    jsonFormat.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    
    HttpResponseMessage res = c.PostAsync<T>(url, TObj, jsonFormat).Result;
    

    【讨论】:

      猜你喜欢
      • 2015-11-15
      • 2016-11-28
      • 2020-01-23
      • 1970-01-01
      • 2019-08-02
      • 2016-05-17
      • 1970-01-01
      • 2013-04-11
      相关资源
      最近更新 更多