asp.net 网页/Razor WebGrid with List<dynamic> 数据源,排序问题
asp.net Web Pages / Razor WebGrid with List<dynamic> datasource, sorting issue
当WebGrid的数据源为List<dynamic>
时,排序不正常。 sortdir 不会在 ASC 和 DESC 之间切换。它总是升序。不过,如果我使用一些 class 的数据源,比如 List<SomeClass>
,那么它工作正常。
我想使用 List<dynamic>
,因为我正在组合来自不同表的字段,我想避免创建额外的 class 并将 List<dynamic>
结果循环到那个额外的class 或将其转换为 class。
下面的示例代码可重现问题。
c#:
List<dynamic> dynList = new List<dynamic>();
for(int i=1; i < 11; i++)
{
dynamic newObj = new
{
Id = i
};
dynList.Add(newObj);
}
WebGrid grid = new WebGrid(rowsPerPage: rowCountPerPage);
grid.Bind(source: dynList, rowCount: totalRowCount, autoSortAndPage: false);
标记:
<div>
List<WebGridColumn> gridColumns = new List<WebGridColumn>();
gridColumns.Add(new WebGridColumn() { ColumnName = "Id", Header = "Id", CanSort = true });
@grid.GetHtml(htmlAttributes: new { id = "tblResult" }
, mode: WebGridPagerModes.All
, numericLinksCount: 10
, columns: grid.Columns(gridColumns.ToArray()))
</div>
你被分配 false 到 autoSortAndPage property.change 这个 属性 到 true
这是 WebGrid 评估其数据源元素类型的方式(在本例中 List() 包含 dynamic 对象的实例。
基本上在内部它正在将列表的元素类型评估为 "object" 而不是实现 IDynamicMetaObjectProvider 的动态类型,这是它用来读取数据的类型source 属性来找出要排序的列名。为什么需要这样做对我来说感觉就像是网格的错误,因为排序信息可能可以从 WebGridColumn 列表中读取。
要完成这项工作,您仍然需要 autoSortAndPage,但您还需要将列表元素更新为实现 IDynamicMetaObjectProvider[= 的动态对象42=]。除了使用示例中的 dynamic 关键字,您还可以替换:
dynamic newObj = new
{
Id = i
};
dynList.Add(newObj);
改为创建 System.Dynamic.ExpandoObject 的实例以添加到您的网格数据源中:
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Id = i;
dynList.Add(obj);
您可以像分配动态对象一样分配 ExpandoObject 的属性。例如 ExpandObject 不 包含 Id 属性,但是 obj.Id = i 赋值 动态添加。
如果您对为什么像这样的框架组件无法按预期工作感到困惑,那么您可以选择调试框架代码,例如:
这就是我所强调的问题。
James 正确评论您需要使用使用 IDynamicMetaObjectProvider 的动态类型。我创建了一个示例,能够重现您的问题,下面是使用类型 System.Dynamic.Expando.
的修复
控制器:
var inventoryList = new List<dynamic>();
for (int i = 0; i < 5; i++)
{
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Id = string.Format("P10{0}", i);
obj.Name = string.Format("{0} Testing", i);
inventoryList.Add(obj);
}
return View(inventoryList);
加价:
@{
var grid = new WebGrid(Model, canSort: true);
grid.Pager(WebGridPagerModes.NextPrevious);
var gridColumns = new List<WebGridColumn>
{
new WebGridColumn()
{
ColumnName = "Id", Header = "Id", CanSort = true
},
new WebGridColumn()
{
ColumnName = "Name", Header = "Name", CanSort = true
}
};
}
<div>
@grid.GetHtml(tableStyle: "webGrid",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
gridColumns.ToArray()
))
当WebGrid的数据源为List<dynamic>
时,排序不正常。 sortdir 不会在 ASC 和 DESC 之间切换。它总是升序。不过,如果我使用一些 class 的数据源,比如 List<SomeClass>
,那么它工作正常。
我想使用 List<dynamic>
,因为我正在组合来自不同表的字段,我想避免创建额外的 class 并将 List<dynamic>
结果循环到那个额外的class 或将其转换为 class。
下面的示例代码可重现问题。
c#:
List<dynamic> dynList = new List<dynamic>();
for(int i=1; i < 11; i++)
{
dynamic newObj = new
{
Id = i
};
dynList.Add(newObj);
}
WebGrid grid = new WebGrid(rowsPerPage: rowCountPerPage);
grid.Bind(source: dynList, rowCount: totalRowCount, autoSortAndPage: false);
标记:
<div>
List<WebGridColumn> gridColumns = new List<WebGridColumn>();
gridColumns.Add(new WebGridColumn() { ColumnName = "Id", Header = "Id", CanSort = true });
@grid.GetHtml(htmlAttributes: new { id = "tblResult" }
, mode: WebGridPagerModes.All
, numericLinksCount: 10
, columns: grid.Columns(gridColumns.ToArray()))
</div>
你被分配 false 到 autoSortAndPage property.change 这个 属性 到 true
这是 WebGrid 评估其数据源元素类型的方式(在本例中 List() 包含 dynamic 对象的实例。
基本上在内部它正在将列表的元素类型评估为 "object" 而不是实现 IDynamicMetaObjectProvider 的动态类型,这是它用来读取数据的类型source 属性来找出要排序的列名。为什么需要这样做对我来说感觉就像是网格的错误,因为排序信息可能可以从 WebGridColumn 列表中读取。
要完成这项工作,您仍然需要 autoSortAndPage,但您还需要将列表元素更新为实现 IDynamicMetaObjectProvider[= 的动态对象42=]。除了使用示例中的 dynamic 关键字,您还可以替换:
dynamic newObj = new
{
Id = i
};
dynList.Add(newObj);
改为创建 System.Dynamic.ExpandoObject 的实例以添加到您的网格数据源中:
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Id = i;
dynList.Add(obj);
您可以像分配动态对象一样分配 ExpandoObject 的属性。例如 ExpandObject 不 包含 Id 属性,但是 obj.Id = i 赋值 动态添加。
如果您对为什么像这样的框架组件无法按预期工作感到困惑,那么您可以选择调试框架代码,例如:
这就是我所强调的问题。
James 正确评论您需要使用使用 IDynamicMetaObjectProvider 的动态类型。我创建了一个示例,能够重现您的问题,下面是使用类型 System.Dynamic.Expando.
的修复控制器:
var inventoryList = new List<dynamic>();
for (int i = 0; i < 5; i++)
{
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Id = string.Format("P10{0}", i);
obj.Name = string.Format("{0} Testing", i);
inventoryList.Add(obj);
}
return View(inventoryList);
加价:
@{
var grid = new WebGrid(Model, canSort: true);
grid.Pager(WebGridPagerModes.NextPrevious);
var gridColumns = new List<WebGridColumn>
{
new WebGridColumn()
{
ColumnName = "Id", Header = "Id", CanSort = true
},
new WebGridColumn()
{
ColumnName = "Name", Header = "Name", CanSort = true
}
};
}
<div>
@grid.GetHtml(tableStyle: "webGrid",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
gridColumns.ToArray()
))