我构建了以下接口:
[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。请各位指点一下,谢谢!
先试试读取json字符串
var result = await response.Content.ReadAsStringAsync();
这个地方是可以正常获取到数据的,获取到的值是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: 试试下面的代码
var model = JsonConvert.DeserializeObject<DataSourceResult>(data, new JsonSerializerSettings(){TypeNameHandling = TypeNameHandling.Objects});
@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);//反序列化 }
返回的结果是一样的,没关系,我再想想办法,多查询一些资料。研究一下原理,如果我找到答案会及时的在这里留言,如果您有空闲时,再帮我看看,打扰您的时间了,谢谢!
@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: 试试TypeNameHandling = TypeNameHandling.All
@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());
}
}
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;};
}
试下!
我这种情况下应该如何处理呢,因为实体集合在DataSourceResult.Data里面,是一个比较复杂的转换,所以就遇到难题了。