具有MVC 2的自定义ViewModel强类型HTML帮助程序在Create上返回null对象?

时间:2010-03-22 18:59:32

标签: asp.net asp.net-mvc-2 strongly-typed-view

尝试使用自定义视图建模创建表单时,我遇到了麻烦。以下是我的类别创建表单的自定义视图模型。

public class CategoryFormViewModel
{
    public CategoryFormViewModel(Category category, string actionTitle)
    {
        Category = category;
        ActionTitle = actionTitle;
    }

    public Category Category { get; private set; }
    public string ActionTitle { get; private set; }
}

这是我的用户控件,其中UI是

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CategoryFormViewModel>" %>

        <h2>
            <span><%= Html.Encode(Model.ActionTitle) %></span>
        </h2>
        <%=Html.ValidationSummary() %>
        <% using (Html.BeginForm()) {%>
        <p>
            <span class="bold block">Başlık:</span>
            <%=Html.TextBoxFor(model => Model.Category.Title, new { @class = "width80 txt-base" })%>
        </p>
        <p>
            <span class="bold block">Sıra Numarası:</span>
            <%=Html.TextBoxFor(model => Model.Category.OrderNo, new { @class = "width10 txt-base" })%>
        </p>        
        <p>
            <input type="submit" class="btn-admin cursorPointer" value="Save" />
        </p>
        <% } %>

当我点击“保存”按钮时,它不会为我绑定类别,因为我正在使用自定义视图模型和类似强类型的html帮助器

<%=Html.TextBoxFor(model => Model.Category.OrderNo) %>

我的html源代码如下

<form action="/Admin/Categories/Create" method="post">
        <p>
            <span class="bold block">Başlık:</span>
            <input class="width80 txt-base" id="Category_Title" name="Category.Title" type="text" value="" />
        </p>
        <p>
            <span class="bold block">Sıra Numarası:</span>
            <input class="width10 txt-base" id="Category_OrderNo" name="Category.OrderNo" type="text" value="" />
        </p>        
        <p>
            <input type="submit" class="btn-admin cursorPointer" value="Kaydet" />
        </p>
        </form>

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:8)

您的视图模型需要一个没有参数的默认构造函数,您需要为每个属性设置公共集方法。默认模型绑定器使用公共setter填充对象。


默认模型绑定器遵循一些规则。它按以下顺序选择要绑定的数据:

  1. 从帖子中填写参数
  2. 您在global.asax.cs
  3. 中的路由定义定义的路由数据
  4. 查询字符串参数
  5. 默认模型绑定器然后使用几种策略绑定到操作方法中的模型/参数:

    1. 确切名称匹配
    2. 与prefix.name匹配,其中prefix是父类,name是子类/ property
    3. 没有前缀的名称(只要没有冲突,您不必担心提供前缀)
    4. 您可以使用“绑定”属性中的多个选项覆盖行为。其中包括:

      • [Bind(Prefix =“someprefix”)] - 强制将地图映射到前缀标识的特定父类。
      • [Bind(Include =“val1,val2”)] - 要绑定的名称的白名单
      • [Bind(Exclude =“val1,val2”)] - 要从默认行为中排除的名称

答案 1 :(得分:2)

您可以使用编辑器模板。将您的ascx控件放在~/Views/Shared/EditorTemplates/SomeControl.ascx中。然后在主视图(aspx页面)中包含这样的模板(假设您的视图强类型为CategoryFormViewModel):

<%= Html.EditorForModel("SomeControl") %>

而不是

<% Html.RenderPartial("SomeControl", Model) %>

答案 2 :(得分:2)

为viewmodel创建默认构造函数并初始化那里的类别

public CategoryFormViewModel() 
{ 
    Category = new Category()
}

在您的控制器操作中接收viewmodel

public ActionResult ActionName(CategoryFormViewModel model)
{
    //here you can access model.Category.Title
}