2012-07-03 2 views
-1

안녕하세요; 모든 종류의 솔루션 바인딩 데이터 webgrid 정적 모델. 하지만 내 데이터는 동적입니다. 제발, 왜 DataTable을 사용합니까? asp.net mvc 3 json 동적 모델을 바인딩하는 방법?

컨트롤러 :



     [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);.

ERROR :

RunTimeBinderException : System.Web.Helpers.WebGrid.WebGrid (System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, 문자열, INT, '에 가장 적합한 오버로드 된 메서드 일치 부울 , 부울, 문자열, 문자열, 문자열, 문자열, 문자열, 문자열, 문자열) '일부 잘못된 인수

DataTable의 사용에 아무 문제가 없다

답변

2

Please dont say: why do you use DataTable?

있습니다. DataTable은 .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 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 엔진 <%%> 구문보기 모델 : ( – programmerist

+0

@programmerist, 어떤 문제가 WebForms 구문을 가지고 있습니까? 내 코드가 '<% %>'입니다. 내 대답을 업데이트했습니다. –

+0

이해할 수 없습니다. 모든 값 사용 public IEnumerable 값 {get; 세트; } 그리고 왜 public IEnumerable을 정의해야합니까? Rows {get; 세트; } – programmerist