首页 新闻 会员 周边 捐助

httpclient调用webapi接口发生的疑问

0
[已解决问题] 解决于 2018-12-02 21:50

我构建了以下接口:

[HttpPost]
public DataSourceResult Get([DataSourceRequest]DataSourceRequest request)
{
   var data = svrbase.Find(x => x.Deleted == false);
   var model =  data.ToDataSourceResult(request);
   return model;
}

返回值是DataSourceResult,它其实是一个复杂类型,包含了分页信息,排序信息,数据列表。

以下是返回值类型

    public class DataSourceResult
    {
        public DataSourceResult();

        public IEnumerable Data { get; set; }
        public int Total { get; set; }
        public IEnumerable<AggregateResult> AggregateResults { get; set; }
        public object Errors { get; set; }
    }

 

以下参数列表

    public class DataSourceRequest
    {
        public DataSourceRequest();

        public int Page { get; set; }
        public int PageSize { get; set; }
        public IList<SortDescriptor> Sorts { get; set; }
        public IList<IFilterDescriptor> Filters { get; set; }
        public IList<GroupDescriptor> Groups { get; set; }
        public IList<AggregateDescriptor> Aggregates { get; set; }
    }

我在传入参数的时候可以正常传入,只是在获取返回值的时候,不知道如何解析,提示解析错误,

我的webapi的调用方法如下所示:

复制代码
HttpClient clint = new HttpClient(); 
var response = await PostAsJsonAsync(path, param);//传入参数,服务器端可以正常返回数据。
response.EnsureSuccessStatusCode();

//执行到下面这一行开始出错:
var result = await response.Content.ReadAsAsync<DataSourceResult>();
复制代码

就是最后一名该如何写,以解析返回来的业务数据呢?就是将返回值解析为DataSourceRequest。请各位指点一下,谢谢!

denli的主页 denli | 初学一级 | 园豆:19
提问于:2018-06-13 07:45
< >
分享
最佳答案
0

先试试读取json字符串

var result = await response.Content.ReadAsStringAsync();
奖励园豆:5
dudu | 高人七级 |园豆:31030 | 2018-06-13 08:04

这个地方是可以正常获取到数据的,获取到的值是json,就是不知道如何将它序列化为DataSourceResult

获取到的值如下所示:

{"data":[{"name":"测试客户","custNbr":null,"abcType":"A","remark":null}],"total":1,"aggregateResults":null,"errors":null}

上面的问题提的有一些问题,我需要将上述获取到的json解析成下面的实体。

    public class DataSourceResult
    {
        public DataSourceResult();

        public IEnumerable Data { get; set; }
        public int Total { get; set; }
        public IEnumerable<AggregateResult> AggregateResults { get; set; }
        public object Errors { get; set; }
    }

然后我将得到的值反序列化,

 if (response.IsSuccessStatusCode)
{
     var data = await response.Content.ReadAsStringAsync();
    var model = JsonConvert.DeserializeObject<DataSourceResult>(data);//反序列化
}
            

得到以下错误:
JsonSerializationException: Cannot create and populate list type System.Collections.IEnumerable. Path 'data', line 1, position 9.
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(JsonReader reader, JsonArrayContract contract, out bool createdFromNonDefaultCreator)

 

我再去学习一下数据序列化解析的问题,如果您看到信息,也可以在下面留言帮我解答一下,谢谢!

denli | 园豆:19 (初学一级) | 2018-06-13 08:32

@denli: 试试下面的代码

var model = JsonConvert.DeserializeObject<DataSourceResult>(data, new JsonSerializerSettings(){TypeNameHandling = TypeNameHandling.Objects});
dudu | 园豆:31030 (高人七级) | 2018-06-13 09:31

@dudu: 

这是我操作的代码:

if (response.IsSuccessStatusCode)
{
    var data = await response.Content.ReadAsStringAsync();
    var model = JsonConvert.DeserializeObject<DataSourceResult>(data, 
     new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects });

    //var model = JsonConvert.DeserializeObject<DataSourceResult>(data);//反序列化
}

返回的结果是一样的,没关系,我再想想办法,多查询一些资料。研究一下原理,如果我找到答案会及时的在这里留言,如果您有空闲时,再帮我看看,打扰您的时间了,谢谢!

denli | 园豆:19 (初学一级) | 2018-06-13 09:42

@dudu: 

原因我已经查到了,但是不知道如何解决,如果您有空的话,请您给予协助,谢谢!

 public class DataSourceResult
    {
        public DataSourceResult();

        public IEnumerable Data { get; set; }
        public int Total { get; set; }
        public IEnumerable<AggregateResult> AggregateResults { get; set; }
        public object Errors { get; set; }
    }

以上代码中,如果我将结构修改为:

public class _DataSourceResult
    {
        public IList Data { get; set; }
        public int Total { get; set; }
        public IList<AggregateResult> AggregateResults { get; set; }
        public object Errors { get; set; }
    }

就可以正常的序列化,也就是不序列化为IEnumerable,而是序列化为IList就没有问题,但是由于这个类是组件提供的,我最终需要将组件序列化为IEnumerable,有比较好的解决方案吗?

denli | 园豆:19 (初学一级) | 2018-06-13 22:07

@denli: 试试TypeNameHandling = TypeNameHandling.All

dudu | 园豆:31030 (高人七级) | 2018-06-13 22:54

@denli: 我这里在 .net core 中测试,默认配置就能正常反序列化

public class DataSourceResult
{
    public IEnumerable<string> Data;
}

class Program
{
    static void Main(string[] args)
    {
        var result = new DataSourceResult
        {
            Data = new List<string> { "a", "b" }
        };

        var json = JsonConvert.SerializeObject(result);
        Console.WriteLine(json);
        result = JsonConvert.DeserializeObject<DataSourceResult>(json);
        Console.WriteLine(result.Data.First());
    }
}
dudu | 园豆:31030 (高人七级) | 2018-06-14 10:10
其他回答(1)
0

public IEnumerable Data { get; set; }

你这个从JSON转换实体的时候标注上类型!比如:

public IEnumerable<A> Data { get; set; }

 

public class A{

public string name{get;set;};

public string custNbr{get;set;};

public string abcType{get;set;};

public string remark{get;set;};

}

试下!

猫出没 | 园豆:219 (菜鸟二级) | 2018-06-13 11:08

我这种情况下应该如何处理呢,因为实体集合在DataSourceResult.Data里面,是一个比较复杂的转换,所以就遇到难题了。

支持(0) 反对(0) denli | 园豆:19 (初学一级) | 2018-06-13 12:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册