无法通过GET反序列化数组
本文关键字:反序列化 数组 GET | 更新日期: 2023-09-27 18:13:28
我正在使用Kendo UI的DataSource向我的ServiceStack服务发送排序信息。如果您使用的是using POST
,我知道这个问题已经解决了,但是我想坚持RESTful设计,所以请求谓词需要是GET
。我将使用以下代码片段进行测试:
var dataSource = new kendo.data.DataSource({
serverSorting: true,
sort: [{ field: "ProductName", dir: "desc" },
{ field: "Category", dir: "asc"}],
serverPaging: true,
page: 2,
pageSize: 5,
transport: {
read: {
url: "/products",
dataType: "json",
contentType: "application/json",
dataType: "jsonp"
},
parameterMap: function (data, type) {
//return kendo.stringify(data);
//return JSON.stringify(data);
//return $.param(data, true);
//data.sort = kendo.stringify(data.sort);
return data;
}
}
});
dataSource.fetch(function () {
console.log(dataSource.view());
});
排序参数被转换成锯齿数组,如:
sort[0][field]: ProductName
sort[0][dir]: desc
sort[1][field]: Category
sort[1][dir]: asc
我的请求DTO是:
public class SortTerm
{
public string field { get; set; }
public string dir { get; set; }
}
public class KendoQuery
{
public List<SortTerm> Sort { get; set; }
public int Skip { get; set; }
public int Take { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
}
所有的简单参数得到反序列化,但我如何在地球上转换Sort
属性,无论是客户端或服务器端,有它正确填充?
请注意,我已经在parameterMap
函数中尝试了各种序列化技术,但我完全被难住了。
编辑
所以这一切归结为:我如何通过$.get()传递对象数组到ServiceStack服务,当jQuery周到地将我的请求重新排列成一个锯齿数组?这是一个请求过滤器,但我必须想象它之前解决了**GET**
请求。
对于使用标准技术的GET
请求,不能使用复杂的数据结构,例如锯齿排序数组的数据结构,因为JSON GET
请求只支持简单的变量,因为这些变量可以转换为查询字符串中的请求参数。因此,对于简单的参数?Page=2&PageSize=5 ...
,请求将正确地形成,但对于sort[0][field]
,这不能指定为查询字符串请求参数。
但是,如果您使用datasource.transport.parameterMap
对搜索条件对象进行字符串化,则可以解决此问题,以便它可以作为参数传递,然后在服务器上进行转换。
parameterMap: function (data, type) {
// Convert the search criteria to a JSON string and store it on value sortJson
data.sortJson = JSON.stringify(data.sort);
// Remove the sort value, as this will be provided by sortJson
delete data.sort;
// Return the data
return data
}
在服务器端,您需要处理将JSON字符串转换为List<SortTerm>
:
public class KendoQuery
{
List<SortTerm> sort;
public List<SortTerm> Sort {
get {
// Handles deserialising the SortJson value
if(sort == null)
sort = ServiceStack.JsonSerializer.DeserializeFromString<List<SortTerm>>(SortJson);
return sort;
}
}
public string SortJson { get; set; }
public int Skip { get; set; }
public int Take { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
}
Scott上面的答案是正确的,但这里是我更以服务器为中心的解决方案。基本上,我从查询字符串手动重建SortTerm
对象。这是可扩展到其他剑道特定的参数,如过滤器&;组。
客户端代码:
<html>
<head>
<meta charset="utf-8">
<title>Kendo UI Snippet</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>
</head>
<body>
<script>
var dataSource = new kendo.data.DataSource({
serverSorting: true,
sort: [{ field: "ProductName", dir: "desc" },
{ field: "Category", dir: "asc" }],
serverPaging: true,
page: 2,
pageSize: 5,
transport: {
read: {
url: "/products",
dataType: "json"
}
}
});
dataSource.fetch(function () {
console.log(dataSource.view());
});
</script>
</body>
</html>
服务器代码(在AppHost实现中):
this.GlobalRequestFilters.Add((req, resp, dto) =>
{
if (dto is KendoQueryBase)
{
KendoQueryBase qb = dto as KendoQueryBase;
if (qb.Sort == null) qb.Sort = new List<SortTerm>();
Dictionary<string, string> qs = req.QueryString.ToDictionary();
var i = 0;
while (qs.ContainsKey("sort[{0}][field]".Fmt(i)))
{
qb.Sort.Add(new SortTerm()
{
field = qs["sort[{0}][field]".Fmt(i)],
dir = qs["sort[{0}][dir]".Fmt(i)]
});
i++;
}
}
});