2012-07-06 50 views
0

右行,我在这个offically无用的(参见前面的问题)MVC 3 HttpPost型号列表<MyType>似乎失去性能

为什么,当我用下面的做,我得到一个可爱的checkboxlistfor,所有的工作很好: (使用扩展方法)

模型

public class My : BusinessCategory 
{ 
     public class MyTypes 
     { 
      public int MyTypeId { get; set; } 
      public string MyTypeName { get; set; } 
      public bool? MyTypeValue { get; set; } 
     } 
     public List<MyTypes> MyTypeListModel { get; set; } 
} 

查看

<fieldset> 
    <legend>My Management</legend> 
    <div style="text-align: left; padding-left: 47%;"> 
     @Html.CheckBoxListForListType(model => model.MyTypeListModel, (MultiSelectList)ViewBag.MyType, Model.ReviewId) 
    </div> 
    <p> 
     <input type="submit" value="Continue" /> 
    </p> 
</fieldset> 

CheckBoxListForListType 扩展(可怕的命名有我所知)

public static MvcHtmlString CheckBoxListForListType<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TProperty>>> expression, MultiSelectList multiSelectList, Guid reviewId, object htmlAttributes = null) 
     { 
      //Derive property name for checkbox name 
      MemberExpression body = expression.Body as MemberExpression; 
      string propertyName = body.Member.Name; 

      //Get currently select values from the ViewData model 
      IEnumerable<TProperty> list = expression.Compile().Invoke(htmlHelper.ViewData.Model); 

      //Convert selected value list to a List<string> for easy manipulation 
      List<string> selectedValues = new List<string>(); 

      if (list != null) 
      { 
       selectedValues = new List<TProperty>(list).ConvertAll<string>(delegate(TProperty i) { return i.ToString(); }); 
      } 

      //Create div 
      TagBuilder divTag = new TagBuilder("div"); 
      divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true); 

      //Add checkboxes 
      foreach (SelectListItem item in multiSelectList) 
      { 
       divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " + 
                "value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>", 
                propertyName, 
                item.Value, 
                GetValueFromDatabaseList(reviewId, propertyName, item.Text.ToLower()), 
                item.Text); 
      } 

      return MvcHtmlString.Create(divTag.ToString()); 
     } 

控制器

public ActionResult My(Guid id) 
     { 
      try 
      { 
       var model = Model(id); 
       SetMyTypeList(model.My); 
       ViewBag.MyType = new MultiSelectList(model.My.MyTypeListModel, "MyTypeValue", "MyTypeName"); 
       return View(model.My); 
      } 
      catch (Exception ex) 
      { 
       ExceptionHelper.WriteLog(ex); 
       return RedirectToAction("Error"); 
      } 
     } 

private void SetMyTypeList(My model) 
     { 
      model.MyTypeListModel = new List<My.MyTypes>(); 
      model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 1, MyTypeName = GetName.GetDisplayName(model, m => m.Option1), MyTypeValue = model.Option1}); 
      model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 2, MyTypeName = GetName.GetDisplayName(model, m => m. Option2), MyTypeValue = model.Option2 }); 
      model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 3, MyTypeName = GetName.GetDisplayName(model, m => m. Option3), MyTypeValue = model.Option3}); 
      model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 4, MyTypeName = GetName.GetDisplayName(model, m => m.Option4), MyTypeValue = model.Option4});   
     } 

然而,当我执行HttpPost作用的结果,MyTypeListModel '失去' 它的属性,即我可以看到,说有两个选择,但他们的名字,价值观,身份证不存在。

[HttpPost] 
    public ActionResult My(Guid id, My model) 
    { 
     try 
     { 
      model.ReviewId = id; 
      var sessionModel = Model(id); 
      sessionModel.My = model; 
      MapCheckBoxListResultswithDatabaseBoolsMy(model); 
      UpdateDb(Categories.catMy, sessionModel); 

      return RedirectToAction("BusinessSummary", new { id = sessionModel.ReviewId }); 
     } 
     catch (Exception ex) 
     { 
      ExceptionHelper.WriteLog(ex); 
      return RedirectToAction("Error"); 
     } 
    } 

是否必须重新设定类型,如果是这样?

像往常一样,许多道歉看起来像是我的一个连续的线索。 '(

+1

没有必要称自己没用,你是在正确的地方提问。 – Ecnalyr 2012-07-06 11:03:30

+0

我仍然试图通读代码,但为什么你在视图中使用ViewBag.MyType? – Ecnalyr 2012-07-06 11:07:31

+0

对不起MUMD - 如果我包含html helper,它可能会更有意义...请稍后参阅EDIT。 – 2012-07-06 11:10:11

回答

0

将行为参数连接起来的过程称为模型绑定,默认情况下,MVC会询问表单,查询字符串和路由以便数据尝试并填充您的类型。你的情况的问题是你的表单字段没有以默认的列表方式命名,你可以在this article by Phil Haack找到关于绑定列表的一些信息,请记住,你正在寻找一个子属性,所以你需要前缀我发现有用的类型适当。

一件事是获得源代码,ASP.NET MVC,然后调试在本地,看看它是寻找当模型绑定。

不要忘记,如果你不想遵循正常的约定(虽然这是明智的),你可以指定你自己的custom model binder你的类型。