C# - Newtonsoft:客户响应的通用类

时间:2016-03-28 11:04:40

标签: c# generics json.net

经过数小时的尝试和研究,我正在寻求你的帮助。

我正在调用一个公共API,除了返回的数据外,它返回相同的结构。

例如,检索站点和区域的REST调用会返回这两个JSON答案:

电台回复:

"response" : {
    "status": { "@attributes": {"code": "0", "message": "OK"} },
    "data" : { 
        "station": [{
            "number": "stationId",
            "name": "stationName",
            "address": "stationAddress",
            "state": "1",
            "latitude": "stationLat",
            "longitude": "stationLong",
            "slotsavailable": "10",
            "bikesavailable": "20",
            "pos": "0",
            "district": "stationDistrict",
            "lastupdate": "2016-03-28T11:47:08+02:00"
        }, {...}, ...]}
}

地区响应:

"response" : {
    "status": { "@attributes": {"code": "0", "message": "OK"} },
    "data" : { "district": [{"id": "districtId", "name": "districtName"}, {...}, ...] }
}

我正在使用带有Newtonsoft.Json的.NET 4.5 / C#解决方案来执行调用。 我想使映射到客户端响应的对象通用,因此调用的执行将如下所示:

var result = await client.Execute<Response<ApiResponseDistrict>>(request);
var result = await client.Execute<Response<ApiResponseStation>>(request);

我的第一次尝试是进行非泛型调用(通过返回的数据创建一个完整的对象),这是成功的。

我的第二次尝试是创建了一个通用对象,所以我使用Newtonsoft库的JsonProperty创建了以下类:

public class ApiResponse<T>
{
    [JsonProperty("response")]
    public Response<T> Response { get; set; }
}

public class Response<T>
{
    [JsonProperty("status")]
    public Status Status { get; set; }
    [JsonProperty("data")]
    public Data<T> Data { get; set; }
}

public class Data<T>
{
    public T ResponseData { get; set; }
}

public class ApiResponseDistrict
{
    [JsonProperty("district")]
    public List<District> Districts { get; set; }
}

public class District
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
}

此时,当我执行调用时,对象Response被赋值,并且其属性Status值等待,但属性Data永远不会被赋值(null)。

我的第三次尝试是继续进行第二次尝试,但使用了它给出的Newtonsoft库的JsonObject(结果相同):

[JsonObject("district")]
public class ApiResponseDistrict
{
    public List<District> Districts { get; set; }
}

由于我是Newtonsoft的新手,我想知道是否可以使用泛型类,正如我试图做的那样,映射调用返回的对象,或者我必须为每个创建一个完整的对象。数据“退回?

感谢您的回答和解释或线索让我找到答案!

1 个答案:

答案 0 :(得分:2)

public class Response<T>
{
    [JsonProperty("status")]
    public Status Status { get; set; }
    [JsonProperty("data")]
    public Data<T> Data { get; set; }
}

public class Data<T>
{
    public T ResponseData { get; set; }
}

这会在数据之间添加另一层,因此响应将如下所示:

{
    "Status": …,
    "Data": {
        "ResponseData": {
            <The actual type T>
        }
    }
}

相反,您要删除ResponseData级别:

public class Response<T>
{
    [JsonProperty("status")]
    public Status Status { get; set; }
    [JsonProperty("data")]
    public T Data { get; set; }
}

例如,对于上面的JSON,您将拥有StationResponseData类:

public class StationResponseData
{
    public List<Station> Stations
    { get; set; }
}

然后你将JSON反序列化为Response<StationResponseData>。然后,Station类将包含numbernameaddress等的所有属性。