【问题标题】:Web API - Converting JSON to Complex Object Type (DTO) with inheritanceWeb API - 使用继承将 JSON 转换为复杂对象类型 (DTO)
【发布时间】:2014-03-29 01:12:57
【问题描述】:

我有以下场景:

public class WidgetBaseDTO
{
    public int WidgetID
    {
        get;
        set;
    }
}

public class WidgetTypeA : WidgetBaseDTO
{
    public string SomeProperty1
    {
        get;
        set;
    }
}


public class WidgetTypeB : WidgetBaseDTO
{
    public int SomeProperty2
    {
        get;
        set;
    }
}

我的 Web 服务返回以下仪表板对象,而 Widgets 集合可以是 A 或 B 类型:

public class DashboardDTO
{
    public List<WidgetBaseDTO> Widgets
    {
        get;
        set;
    }
}

我的问题是,虽然客户端接收到正确的 JSON 内容,这取决于 Widget 类型,但在读取响应内容时,它们都被转换为 WidgetBaseDTO。将这些对象转换为相关类型的正确方法是什么?

这是读取响应的方式:

string relativeRequestUri = string.Format("api/dashboards/GetDashboard?dashboardID={0}", dashboardID);
using (var client = new HttpClient())
{
    // set client options
    client.BaseAddress = this.BaseUri;
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // make request               
    HttpResponseMessage response = client.GetAsync(relativeRequestUri).Result;
    if (response.IsSuccessStatusCode)
    {                   
        DashboardDTO dashboard = response.Content.ReadAsAsync<DashboardDTO>().Result;
    }

【问题讨论】:

  • 您能分享一下您是如何在客户端读取响应的吗?
  • 刚刚分享了一段代码。请见上文。

标签: json asp.net-web-api dto dotnet-httpclient


【解决方案1】:

我相信在收到回复后,您可能会尝试将 WidgetBaseDTO 转换为 WidgetTypeAWidgetTypeB 并且您看到的是 null?如果是,那么您可以在对服务器上的 Json 格式化程序进行以下设置后尝试...确保在客户端的 json 格式化程序上也进行此设置。

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects;

上述设置将导致WidgetTypeAWidgetTypeB 的类型信息被放在网络上,从而向客户端提示正在反序列化的对象的实际类型...您可以尝试查看响应的有线格式以获得一个想法......

客户端:

JsonMediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects;
WidgetBaseDTO baseDTO = resp.Content.ReadAsAsync<WidgetBaseDTO>(new MediaTypeFormatter[] { jsonFormatter }).Result;

【讨论】:

  • 在服务器上添加了这个,它似乎正确地返回了响应中的对象类型,但不太清楚在客户端上的哪里添加这一行。特别是因为我的客户没有对 system.web.http.GlobalConfiguration 的引用。还想知道是否有一种方法可以在每次通话的基础上而不是在全局范围内做到这一点......
  • 我用您在客户端的操作方式更新了我的答案。 ReadAsAsync 具有允许您显式提供格式化程序的重载。
猜你喜欢
  • 2021-12-27
  • 1970-01-01
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多