如何实现可用于反序列化多级json的class?
How to implement class which can be used to de-serialize multiple level json?
我有一个 json 字符串,例如:
{
"sn_request": {
"sn_body": {
"getExtensionlink": {
"pid": null,
"productUrl": "https://xx",
"promotionId": null,
"quanUrl": null,
"subUser": null,
"sugsUrl": null
}
}
}
}
由于节点 getExtensionlink
是动态的,我实现 class 如下所示:
public class SnRequest<T>
{
public T sn_body { get; set; }
}
public class Root<T>
{
public SnRequest<T> sn_request { get; set; }
}
public class GetExtensionlink<T>
{
public T getExtensionlink { get; set; }
}
public class GetExtensionlinkTest
{
[JsonProperty("pid")]
public string Pid { get; set; }
[JsonProperty("productUrl")]
public string ProductUrl { get; set; }
[JsonProperty("promotionId")]
public string PromotionId { get; set; }
[JsonProperty("quanUrl")]
public string QuanUrl { get; set; }
[JsonProperty("subUser")]
public string SubUser { get; set; }
[JsonProperty("sugsUrl")]
public string SugsUrl { get; set; }
}
然后,通过下面的代码反序列化它:
var getExtensionlinkT = new GetExtensionlinkTest
{
ProductUrl = @"https://m.suning.com/product/0071237944/000000012059477830.html?utm_campaign=1608091212288684183&utm_source=share-copyurl&utm_medium=2cd5ed46-copyurl"
};
var root = new Root<GetExtensionlink<GetExtensionlinkTest>>
{
sn_request = new SnRequest<GetExtensionlink<GetExtensionlinkTest>>
{
sn_body = new GetExtensionlink<GetExtensionlinkTest>
{
getExtensionlink = getExtensionlinkT
}
}
};
var result = await client.PostAsJsonAsync<Root<GetExtensionlink<GetExtensionlinkTest>>, TestResponseBase<GetExtensionlink<GetExtensionlinkResponse>>>(@"https://xx", root);
但是,这一行Root<GetExtensionlink<GetExtensionlinkTest>
让人有点难以接受。
我希望是否有任何方法可以使上面的代码干净和可重用。
使用 JObject
怎么样?
简化示例
class Root
{
public JObject Body { get; set; }
}
class X
{
public int Id { get; set; }
}
class Y
{
public string Desc { get; set; }
}
所以我有一个顶级实体和 2 个不同的子实体。
序列化
var a = new Root { Body = JObject.FromObject(new X {Id = 1}) };
var b = new Root { Body = JObject.FromObject(new Y {Desc = "Test"}) };
var jsonA = JsonConvert.SerializeObject(a);
var jsonB = JsonConvert.SerializeObject(b);
Console.WriteLine(jsonA);
Console.WriteLine(jsonB);
这里我们使用FromObject
将子实体转换为JObject
。
输出
{"Body":{"Id":1}}
{"Body":{"Desc":"Test"}}
反序列化
var rootA = JsonConvert.DeserializeObject<Root>(jsonA);
var rootB = JsonConvert.DeserializeObject<Root>(jsonB);
var x = rootA.Body.ToObject<X>();
var y = rootB.Body.ToObject<Y>();
Console.WriteLine(x.Id);
Console.WriteLine(y.Desc);
这里我们使用ToObject
将JObject
s子实体转换成。
使用这种方法,您无需一直向下传递通用参数。
我有一个 json 字符串,例如:
{
"sn_request": {
"sn_body": {
"getExtensionlink": {
"pid": null,
"productUrl": "https://xx",
"promotionId": null,
"quanUrl": null,
"subUser": null,
"sugsUrl": null
}
}
}
}
由于节点 getExtensionlink
是动态的,我实现 class 如下所示:
public class SnRequest<T>
{
public T sn_body { get; set; }
}
public class Root<T>
{
public SnRequest<T> sn_request { get; set; }
}
public class GetExtensionlink<T>
{
public T getExtensionlink { get; set; }
}
public class GetExtensionlinkTest
{
[JsonProperty("pid")]
public string Pid { get; set; }
[JsonProperty("productUrl")]
public string ProductUrl { get; set; }
[JsonProperty("promotionId")]
public string PromotionId { get; set; }
[JsonProperty("quanUrl")]
public string QuanUrl { get; set; }
[JsonProperty("subUser")]
public string SubUser { get; set; }
[JsonProperty("sugsUrl")]
public string SugsUrl { get; set; }
}
然后,通过下面的代码反序列化它:
var getExtensionlinkT = new GetExtensionlinkTest
{
ProductUrl = @"https://m.suning.com/product/0071237944/000000012059477830.html?utm_campaign=1608091212288684183&utm_source=share-copyurl&utm_medium=2cd5ed46-copyurl"
};
var root = new Root<GetExtensionlink<GetExtensionlinkTest>>
{
sn_request = new SnRequest<GetExtensionlink<GetExtensionlinkTest>>
{
sn_body = new GetExtensionlink<GetExtensionlinkTest>
{
getExtensionlink = getExtensionlinkT
}
}
};
var result = await client.PostAsJsonAsync<Root<GetExtensionlink<GetExtensionlinkTest>>, TestResponseBase<GetExtensionlink<GetExtensionlinkResponse>>>(@"https://xx", root);
但是,这一行Root<GetExtensionlink<GetExtensionlinkTest>
让人有点难以接受。
我希望是否有任何方法可以使上面的代码干净和可重用。
使用 JObject
怎么样?
简化示例
class Root
{
public JObject Body { get; set; }
}
class X
{
public int Id { get; set; }
}
class Y
{
public string Desc { get; set; }
}
所以我有一个顶级实体和 2 个不同的子实体。
序列化
var a = new Root { Body = JObject.FromObject(new X {Id = 1}) };
var b = new Root { Body = JObject.FromObject(new Y {Desc = "Test"}) };
var jsonA = JsonConvert.SerializeObject(a);
var jsonB = JsonConvert.SerializeObject(b);
Console.WriteLine(jsonA);
Console.WriteLine(jsonB);
这里我们使用FromObject
将子实体转换为JObject
。
输出
{"Body":{"Id":1}}
{"Body":{"Desc":"Test"}}
反序列化
var rootA = JsonConvert.DeserializeObject<Root>(jsonA);
var rootB = JsonConvert.DeserializeObject<Root>(jsonB);
var x = rootA.Body.ToObject<X>();
var y = rootB.Body.ToObject<Y>();
Console.WriteLine(x.Id);
Console.WriteLine(y.Desc);
这里我们使用ToObject
将JObject
s子实体转换成。
使用这种方法,您无需一直向下传递通用参数。