【问题标题】:How to bind json dynamic model in asp.net mvc 3?如何在asp.net mvc 3中绑定json动态模型?
【发布时间】:2012-07-03 07:37:23
【问题描述】:

你好;各种解决方案绑定数据webgrid静态模型。但我的数据是动态的。请不要说:你为什么使用DataTable?

控制器:



      [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(string submitButton, FormCollection fc)
        {
            ViewData["Customers"] = new SelectList(CustomerOperation.GetCustomers().Items, "Id", "Name", null);
            ViewData["Jobs"] = new SelectList(JobOperation.GetCustomersAssemblyList().Items, "scheduleId", "name", null);
            int Id = ConvertUtil.ToInt(fc["Customers"]);
            int scheduleId = ConvertUtil.ToInt(fc["Jobs"]);
            DataTable dt = JobOperation.GetJobsBySchedulerIdAndCustomerId(scheduleId, Id);
           return View(Json(dt,JsonRequestBehavior.AllowGet));
        }

查看:


 <% 
     List<WebGridColumn> cols = new List<WebGridColumn>();
     WebGrid grid = null;
     if (Model != null)
     {
           grid = new WebGrid(source: Model.Data, rowsPerPage: 3);
         
         System.Reflection.PropertyInfo[] propertiesofColumn = new System.Reflection.PropertyInfo[] { };
         foreach (object column in Model)
         {
             propertiesofColumn = column.GetType().GetProperties();
         }

         foreach (System.Reflection.PropertyInfo propInfo in propertiesofColumn)
         {
             cols.Add(grid.Column(propInfo.Name, propInfo.Name));
         }

       
     }
     
   using (Html.BeginForm())
      { %>

grid = new WebGrid(source: 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, string, string, string, string)' 有一些无效参数

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 model-view-controller


    【解决方案1】:

    请不要说:你为什么使用DataTable?

    使用DataTable没有错。 DataTables 早在 .NET 时代就已经存在,完全可以理解的是,仍有大量现有代码依赖于它们。但这不是为什么那些 DataTables 应该跨越从控制器到视图的边界的原因。控制器应始终将视图模型传递给视图。那么让我们从定义这个视图模型开始吧:

    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 class RequestViewModel
    {
        public string SubmitButton { get; set; }
        public int Customers { get; set; }
        public int Jobs { get; set; }
    }
    

    现在,我们如何隐藏这个DataTable?我们可以编写一个扩展方法,将其转换为动态对象:

    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 --") %>
    

    【讨论】:

    • 首先我要说谢谢但我有两个问题:我的问题是剃须刀我不知道剃须刀我无法翻译 aspx 引擎 语法视图模型:(
    • @programmerist,您在使用 WebForms 语法时遇到了什么问题?您只需将我的代码中的@ 替换为&lt;% %&gt;。我已经更新了我的答案。
    • 我无法理解。为什么不使用任何值 public IEnumerable Values { get;放; } 以及为什么定义 public IEnumerable Rows{ get;放; }
    • 因为这是我在代码中犯的一个错误 :-) model.Rows = dt.AsDynamicEnumerable(); 当然应该是 model.Values = dt.AsDynamicEnumerable();。我已经更新了我的答案来修复它。显然,如果您愿意,可以使用 Rows 作为属性名称。
    • 你的视图是强类型到 MyViewModel 的吗?如果您收到此错误,我想这不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多