在RestSharp中动态反序列化为属性

时间:2015-05-04 16:12:44

标签: c# restsharp

我正在使用Harvest API,我尝试尽可能简单地自动映射实体,不幸的是,当我执行GET /projects之类的请求时,它会生成如下结果:

[{
    project: {
        name: "Test"
    }
},
{
    project: {
        name: "Test 2"
}]

在RestSharp中,我不能直接这样做:

client.Execute<List<Project>>(request)

因为它将寻找名为Project的属性。所以我必须创建另一个具有该属性的类,并将其命名为:

client.Execute<List<ProjectContainer>>(request)

我不想制作一个容器&#39;每个实体的类,所以我认为我找到了一个聪明的解决方案,可以创建一个我可以使用的类:

public class ListContainer<T> where T : IHarvestEntity
{
    public T Item { get; set; }
}

但是,当然,反序列化器不知道它需要将实体名称(或&#34; Project&#34;)映射到属性Item。在restsharp文档中,我发现我可以使用[DeserializeAs(Name = "CustomProperty")]告诉反序列化器哪个字段映射到此属性。但是,属性只允许常量,这意味着我无法做到:

[DeserializeAs(Name = typeof(T).FullName)]
public T Item { get; set; }

有谁知道这个聪明的解决方案?所以我不必创建10个不同的容器类?

2 个答案:

答案 0 :(得分:8)

我建议你使用Jath的XPath等价物。使用Json.NET,您可以parse字符串并创建动态对象。

使用SelectToken,您可以查询值,或使用Linq

代码看起来像这样(我没有测试它):

// execute the request
RestResponse response = client.Execute(request);
var content = response.Content; // raw content as string

JObject o = JObject.Parse(content);

IList<string> projectNames = o.SelectToken("project").Select(s => (string)s.name).ToList();

您可以根据自己的喜好对路径进行编码或配置路径。

---编辑---

这是我测试的一个例子,将json字符串转换为项目列表。

var projects = JArray.Parse(response.Content).Select(r => new Project(r["project"]["name"].Value<string>())).ToList();

答案 1 :(得分:3)

为了保持简单,您可以使用List<dynamic>并使用单行按名称访问属性/属性。

var names = client.Execute<List<dynamic>>(request).Data.Select(
              item => item["project"]["name"]).ToList(); // list of names

如果这还不够,那么您可以即兴创作自己的映射器并提取例如Project个实例:

var projects = client.Execute<List<dynamic>>(request).Data.Select(
                 item => Map<Project>(item)).ToList(); // list of Project instances

其中Map方法可能类似于

public T Map<T>(dynamic item) where T : class
{
    // inline for clarity
    var mappings = new Dictionary<Type,Func<dynamic,object>>
        {
            { typeof(Project), map => new Project(map["project"]["name"]) }
        };

    return (T)mappings[typeof(T)].Invoke(item);
}

给定Project定义为

public class Project
{
    public Project(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}