【问题标题】:Deserialize different json documents to the same object structure将不同的json文档反序列化为同一个对象结构
【发布时间】:2017-08-16 06:38:27
【问题描述】:

我正在为这种情况寻找最佳方法:

我想创建 WebApi,它会向客户端返回一些对象,例如:

{
   id: 1,
   name: "name1",
   type: "type1"
}

我可以从不同的数据提供者(文档数据库)中检索这些数据,这些数据提供者可以具有不同的数据结构,例如:

第一来源:

{
   id: 1,
   name: "name1",
   type: "type1"
}

第二来源:

{
   productId: 1,
   productName: "product",
   productType: "type"
}

第三来源:

{
   itemId: 1,
   itemName: "name",
   itemType: "type"
}

使用下一个数据提供者轻松扩展的最佳方法是什么?我想补充一点,我一直在考虑 JSON.NET lib。所以我相信我正在寻找依赖于数据提供者的不同 json 映射的示例?任何人都可以提供一些例子吗?让我补充一点,这只是“只读”场景,所以我的意思是 WebApi 调用不同的 dbs => 对某个对象进行反序列化 => 最终对对象本身进行操作 => 通过 http 发送。

【问题讨论】:

  • 我会简单地使用从每个提供者的结果到您自己的可重用映射的映射,即使数据看起来相似。您将尝试制作的任何通用内容都必然会在下一个新提供者处中断。
  • 最好的办法是 IMO 使用 AutoMapper

标签: c# json asp.net-web-api json.net deserialization


【解决方案1】:

Automapper 和三个不同的 dto 将是 imo 最正确的方式。但是如果你想用一种非常简单的方式来做,你可以只创建一个具有所有不同属性的类,并让相应的属性使用相同的支持变量

class Item
{
    string _id;

    public string id
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }
    public string productId
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }
    public string itemId
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }

    string _name;

    public string name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    public string productName
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    public string itemName
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }

    string _type;

    public string type
    {
        get
        {
            return _type;
        }
        set
        {
            _type = value;
        }
    }
    public string productType
    {
        get
        {
            return _type;
        }
        set
        {
            _type = value;
        }
    }
    public string itemType
    {
        get
        {
            return _type;
        }
        set
        {
            _type = value;
        }
    }
}

【讨论】:

    【解决方案2】:

    另一种可能的方法是将serialization settings 与覆盖ResolvePropertyName 方法的自定义contract resolver 对象一起使用。

    【讨论】:

      【解决方案3】:

      您可以使用 AutoMapper 来解决这个问题。

      http://automapper.org/

      https://github.com/AutoMapper/AutoMapper/wiki/Getting-started

      试试下面的示例

          public class ReturnObject
          {
              public int Id { get; set; }
              public string Name { get; set; }
              public string Type { get; set; }
          }
          public class Source1
          {
              public int Id { get; set; }
              public string Name { get; set; }
              public string Type { get; set; }
          }
          public class Source2
          {
              public int ProductId { get; set; }
              public string ProductName { get; set; }
              public string ProductType { get; set; }
          }
          public class Source3
          {
              public int ItemId { get; set; }
              public string ItemName { get; set; }
              public string ItemType { get; set; }
          }
      

      AutoMapper 配置文件

      public class AutoMapperProfile : Profile
      {
          public AutoMapperProfile()
          {
              //Same properties
              CreateMap<Source1, ReturnObject>();
      
              //Difference properties
              CreateMap<Source2, ReturnObject>()
                  .ForMember(dest => dest.Id, opt => opt.MapFrom(f => f.ProductId))
                  .ForMember(dest => dest.Name, opt => opt.MapFrom(f => f.ProductName))
                  .ForMember(dest => dest.Type, opt => opt.MapFrom(f => f.ProductType));
              CreateMap<Source3, ReturnObject>()
                  .ForMember(dest => dest.Id, opt => opt.MapFrom(f => f.ItemId))
                  .ForMember(dest => dest.Name, opt => opt.MapFrom(f => f.ItemName))
                  .ForMember(dest => dest.Type, opt => opt.MapFrom(f => f.ItemType));
          }
      }
      

      【讨论】:

      • 所以问题是我想避免定义那些“SourceX”实体。而不是直接从 documentdb 反序列化到 ReturnObject
      猜你喜欢
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多