C# 如何在asp.net mvc 3中绑定json动态模型?
你好各种解决方案绑定数据webgrid静态模型。但我的数据是动态的。请不要说:为什么使用DataTable? 控制器: 视图:C# 如何在asp.net mvc 3中绑定json动态模型?,c#,asp.net-mvc,asp.net-mvc-3,model-view-controller,C#,Asp.net Mvc,Asp.net Mvc 3,Model View Controller,你好各种解决方案绑定数据webgrid静态模型。但我的数据是动态的。请不要说:为什么使用DataTable? 控制器: 视图: grid=new WebGrid(源:Model.Data,rowsPerPage:3)上发生错误 错误: RunTimeBinderException:与“System.Web.Helpers.WebGrid.WebGrid(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEn
grid=new WebGrid(源:Model.Data,rowsPerPage:3)上发生错误
错误:
RunTimeBinderException:与“System.Web.Helpers.WebGrid.WebGrid(System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable,string,int,bool,bool,string,string,string)”匹配的最佳重载方法具有一些无效参数
请不要说:为什么使用DataTable
使用DataTable没有什么错。DataTables早在.NET的早期就已经存在了,可以完全理解的是,仍然有许多现有代码依赖于它们。但这并不是这些数据表应该从控制器到视图跨越边界的原因。控制器应始终将视图模型传递给视图。那么让我们从定义这个视图模型开始,好吗
public class MyViewModel
{
public int? SelectedCustomerId { get; set; }
public IEnumerable<SelectListItem> Customers { get; set; }
public int? SelectedJobId { get; set; }
public IEnumerable<SelectListItem> Jobs { get; set; }
public IEnumerable<string> Columns { get; set; }
public IEnumerable<object> Values { get; set; }
}
现在,我们如何隐藏这个数据表
?我们可以编写一个扩展方法,将其转换为动态对象:
public static class DataTableExtensions
{
private sealed class Row : DynamicObject
{
private readonly DataRow _row;
public Row(DataRow row)
{
_row = row;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var value = _row.Table.Columns.Contains(binder.Name);
result = value ? _row[binder.Name] : null;
return value;
}
}
public static IEnumerable<dynamic> AsDynamicEnumerable(this DataTable table)
{
return table.AsEnumerable().Select(row => new Row(row));
}
}
公共静态类DataTableExtensions
{
私有密封类行:DynamicObject
{
私有只读数据行_行;
公用行(数据行)
{
_行=行;
}
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果)
{
var值=_row.Table.Columns.Contains(binder.Name);
结果=值?\行[活页夹名称]:空;
返回值;
}
}
公共静态IEnumerable作为动态numerable(此数据表)
{
return table.AsEnumerable().Select(row=>newrow(row));
}
}
到目前为止还不错。在控制器操作中,我们将创建我们的视图模型:
[HttpPost]
public ActionResult Index(RequestViewModel request)
{
int id = request.Customers;
int scheduleId = request.Jobs;
DataTable dt = JobOperation.GetJobsBySchedulerIdAndCustomerId(scheduleId, id);
// Now let's build the view model for the result:
var model = new MyViewModel();
model.Columns = dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName);
model.Values = dt.AsDynamicEnumerable();
model.Customers = new SelectList(CustomerOperation.GetCustomers().Items, "Id", "Name");
model.Jobs = new SelectList(JobOperation.GetCustomersAssemblyList().Items, "scheduleId", "name");
return View(model);
}
[HttpPost]
公共操作结果索引(RequestViewModel请求)
{
int id=请求。客户;
int scheduleId=request.Jobs;
DataTable dt=JobOperation.GetJobsBySchedulerId和CustomerId(scheduleId,id);
//现在,让我们为结果构建视图模型:
var模型=新的MyViewModel();
model.Columns=dt.Columns.Cast().Select(x=>x.ColumnName);
model.Values=dt.asdynamicnumerable();
model.Customers=newselectList(CustomerOperation.GetCustomers().Items,“Id”,“Name”);
model.Jobs=new SelectList(JobOperation.getCustomerAssemblyList().Items,“scheduleId”,“name”);
返回视图(模型);
}
现在我们当然可以有一个强类型视图:
<%
var grid = new WebGrid(Model.Values);
var columns = Model.Columns.Select(x => grid.Column(x));
%>
<%= grid.GetHtml(columns: columns) %>
// and then we could have dropdowns and other stuff
<%= Html.DropDownListFor(x => x.SelectedCustomerId, Model.Customers, "-- customer --") %>
<%= Html.DropDownListFor(x => x.SelectedJobId, Model.Jobs, "-- job --") %>
grid.Column(x));
%>
//然后我们可以有下拉列表和其他东西
x、 SelectedCustomerId,Model.Customers,“--customer-->”
x、 SelectedJobId,Model.Jobs,“--job-->”
首先我要说谢谢,但我有两个问题:我的问题是razor我不知道razor我无法翻译aspx引擎语法视图模型:(@programmerist,WebForms语法有什么问题?你只需将我代码中的@
替换为
。我已经更新了我的答案。我不明白。为什么不使用任何值public IEnumerable Values{get;set;}以及为什么定义public IEnumerable Rows{get;set;}因为这是我在代码中犯的错误:-)model.Rows=dt.asdynamicnumerable();
当然应该是model.Values=dt.asdynamicnumerable()
。我已经更新了我的答案来修复它。显然,如果您愿意,您可以使用行
作为属性名。您的视图是否强类型化为MyViewModel?如果您遇到此错误,我想不会。
public static class DataTableExtensions
{
private sealed class Row : DynamicObject
{
private readonly DataRow _row;
public Row(DataRow row)
{
_row = row;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var value = _row.Table.Columns.Contains(binder.Name);
result = value ? _row[binder.Name] : null;
return value;
}
}
public static IEnumerable<dynamic> AsDynamicEnumerable(this DataTable table)
{
return table.AsEnumerable().Select(row => new Row(row));
}
}
[HttpPost]
public ActionResult Index(RequestViewModel request)
{
int id = request.Customers;
int scheduleId = request.Jobs;
DataTable dt = JobOperation.GetJobsBySchedulerIdAndCustomerId(scheduleId, id);
// Now let's build the view model for the result:
var model = new MyViewModel();
model.Columns = dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName);
model.Values = dt.AsDynamicEnumerable();
model.Customers = new SelectList(CustomerOperation.GetCustomers().Items, "Id", "Name");
model.Jobs = new SelectList(JobOperation.GetCustomersAssemblyList().Items, "scheduleId", "name");
return View(model);
}
<%
var grid = new WebGrid(Model.Values);
var columns = Model.Columns.Select(x => grid.Column(x));
%>
<%= grid.GetHtml(columns: columns) %>
// and then we could have dropdowns and other stuff
<%= Html.DropDownListFor(x => x.SelectedCustomerId, Model.Customers, "-- customer --") %>
<%= Html.DropDownListFor(x => x.SelectedJobId, Model.Jobs, "-- job --") %>