【问题标题】:How to Deserialize json that has properties containing different objects?如何反序列化具有包含不同对象的属性的json?
【发布时间】:2017-09-09 17:20:13
【问题描述】:

我目前正在为Zoho Books API 开发一个.NET 客户端,以便在我的组织中集成一些数据。我一直在努力反序列化 API 返回的 json。问题是由于继承和不同的属性名称。我想我正在考虑创建一个自定义转换器,以避免为了几个不同的字段而为每个模型创建响应类型。

我能够创建一个适用于父响应的自定义转换器,如下所示:

{
     "code" : 0,
     "message" : "success",
     "invoice" : { // This field varies by model
         "invoice_id" : "..."
     }
}

我为此自定义转换器创建了a gist

自定义转换器的一个问题是,当我从 Web 客户端向下传递通用返回类型时,我需要基本响应格式或分页响应格式的它,而泛型在这里失败了。我的转换器不适用于分页响应。

我这样定义了 ZohoBooks Response 的基本类型:

namespace ZohoBooks4Net.Responses
{
    public class ZohoBooksResponse<T> : IZohoBooksResponse<T>
    {
        /// <summary>
        /// Zoho Books error code. This will be zero for a success response and non-zero in case of an error.
        /// </summary>

        [JsonProperty("code")]
        public int Code { get; set; }

        /// <summary>
        /// Message for the invoked API.
        /// </summary>

        [JsonProperty("message")]
        public string Message { get; set; }

        /// <summary>
        /// Comprises the invoked API’s Data.
        /// </summary>
        public T Resource { get; set; }
    }
}

Resource 是我在响应中调用的第三个字段。

但是,当响应以分页形式返回时,它会添加另一个字段。

{
  "code": 0,
  "message": "success",
  "contacts": [
    { "..." }
  ],
  "page_context": {
    "page": 1,
    "per_page": 200,
    "has_more_page": false,
    "applied_filter": "Status.All",
    "sort_column": "contact_name",
    "sort_order": "D"
  }
}

所以我创建了这个对象来描述它:

namespace ZohoBooks4Net.Responses.PaginatedResponses
{
    public class PaginatedResponse<T> : ZohoBooksResponse<T>, IPaginatedResponse<T>
    {
        [JsonProperty("page_context")]
        public PageContext Context { get; set; }
    }

    public class PageContext
    {
        [JsonProperty("page")]
        public int Page { get; set; }

        [JsonProperty("per_page")]
        public int PerPage { get; set; }

        [JsonProperty("has_more_page")]
        public bool HasMorePage { get; set; }
    }
}

如果有人有任何解决方案,我将不胜感激。

【问题讨论】:

  • 在服务器端扁平化你的模型并给客户端一个扁平化模型不是更容易吗?
  • 我不是 Zoho 员工。如果由我决定,我会的。他们提供的某些字段(如代码和消息)可能位于标题中。
  • @dbc 我发现转换器是用来写的,不是用来读的。
  • @dbc 使用您评论中的资源,我在转换器中实现了 ReadJson 方法。如果有人想让它更好地工作,我也会把它作为一个要点。我还通过将属性更改为通用类而不是对象来更改它以满足我的需要。我会给你答案,这样你就可以得到评论。感谢领导! DynamicPropertyConverter

标签: c# json json.net


【解决方案1】:

书籍已在 github 中托管 .Net 库。在Subscription java client 中,页面上下文和资源是分开处理的。

【讨论】:

  • 我一直在 GitHub 上搜索这个!谢谢你给我看。但是我实际上正在寻找一个实现 .NET Standard 的工具,因此它适用于任何 .NET 项目(我们使用 Linux 和 .NET Core 以及 Xamarin 项目)。我现在看到 Zoho 有一个 GitHub 帐户。如果我需要一些灵感,我将不得不查看代码。
【解决方案2】:

您是否尝试过使用 json2csharp Web 应用程序工具?它将根据您的 JSON 响应创建所需的类和一个可与 Newtonsoft JsonCovnert 的 DeserializeObject 方法一起使用的根对象。

【讨论】:

  • 我其实更喜欢jsonutils.com。它更适合我的需要。我在这里要做的是为响应创建一个基类,并将响应返回的模型分开,因为每个响应都将具有相同的冗余属性(代码和消息)。这些属性与模型本身无关。
【解决方案3】:

从评论者那里获取referenced post,我实现了文章发布者创建的ReadJson方法。这解决了我的问题。这是 Github Gist 上 DynamicPropertyNameConverter 的链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多