2012-07-03 2 views
-1

Hi; все виды решений, связывающих статические модели webgrid данных. Но мои данные динамичны. Пожалуйста, не говорите: зачем вы используете DataTable? Как связать динамическую модель json в asp.net mvc 3?

Контроллер:



     [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()) 
     { %> 

Ошибка произошла на сетке = новый WebGrid (источник: Model.Data, rowsPerPage: 3);.

ОШИБКА:

RunTimeBinderException: Лучший перегруженный метод подходит для «System.Web.Helpers.WebGrid.WebGrid (System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, строка, INT, BOOL , BOOL, строка, строка, строка, строка, строка, строка, строка)»имеет некоторые недопустимые аргументы

ответ

2

Please dont say: why do you use 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 --") %> 
+0

Прежде всего я хотел бы сказать спасибо, но у меня есть 2 вопроса: моя проблема - это бритва, я понятия не имею, что бритва я не могу перевести aspx engine <%%> синтаксис view model :( – programmerist

+0

@programmerist, какие проблемы у вас возникают с синтаксисом WebForms? Вы просто заменяете '@' в мой код с '<% %>'. Я обновил свой ответ. –

+0

Я не могу понять. Почему вы не использовать любое значение public IEnumerable Значения {get; задавать; } И зачем определять public IEnumerable Строки {get; задавать; } – programmerist

Смежные вопросы