MVC3:在回发时未重构的模型部分

时间:2011-09-22 13:23:12

标签: asp.net-mvc-3 model-binding

我的模型的部分内容未在回发时正确重建。

模型

public class DemographicsModel
{
    public List<QuestionModel> Questions { get; set; }
}

public abstract class QuestionModel
{
    [HiddenInput(DisplayValue = false)]
    public int ID { get; set; }

    [HiddenInput(DisplayValue = false)]
    public string Title { get; set; }
}

public abstract class ChooseQuestionModel : QuestionModel
{
    public abstract List<SelectListItem> Items { get; set; }
}

public class ChooseManyQuestionModel : ChooseQuestionModel
{
    [Required]
    [DataType("CheckBoxList")]
    public override List<SelectListItem> Items { get; set; }
}

浏览

ChooseManyQuestionModel.cshtml

@model X.Y.Z.ChooseManyQuestionModel

<div class="Form Wide NoLabel">
    <div class="Title">@this.Model.Title</div>
    @Html.TypeStamp()
    @Html.EditorFor(m => m.ID)
    @Html.EditorFor(m => m.Title)
    @Html.EditorFor(m => m.Items)
</div>

CheckBoxList.cshtml

@model IEnumerable<SelectListItem>

@if (!this.Model.IsNullOrEmpty())
{
    foreach (var item in this.Model)
    {
        <div>
            @Html.HiddenFor(m => item.Value)
            @Html.HiddenFor(m => item.Text)
            @Html.CheckBoxFor(m => item.Selected)
            @Html.LabelFor(m => item.Selected, item.Text)
        </div>
    }
}

我认为问题出在CheckBoxList.cshtml中,因为这些项目不会在回发时重新构建。

HTML输出

<div class="Form Wide NoLabel">
    <div class="Title">Question title displays here?</div>
        <input id="Questions_1___xTypeStampx_" name="Questions[1]._xTypeStampx_" type="hidden" value="Hrxh2HjDRorBAZWo18hsC0OvbJwyswpDkfTBfNF2NC8=" />
        <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="Questions_1__ID" name="Questions[1].ID" type="hidden" value="76" />
        <input id="Questions_1__Title" name="Questions[1].Title" type="hidden" value="Question title displays here?" />
        <div>
            <input id="Questions_1__Items_item_Value" name="Questions[1].Items.item.Value" type="hidden" value="148" />
            <input id="Questions_1__Items_item_Text" name="Questions[1].Items.item.Text" type="hidden" value="Organization Type 1" />
            <input data-val="true" data-val-required="The Selected field is required." id="Questions_1__Items_item_Selected" name="Questions[1].Items.item.Selected" type="checkbox" value="true" /><input name="Questions[1].Items.item.Selected" type="hidden" value="false" />
            <label for="Questions_1__Items_item_Selected">Organization Type 1</label>
        </div>
    </div>
</div>  

控制器

public class AccountController : BaseController
{
    public ActionResult Demographics()
    {
        return this.View(new DemographicsModel());
    }

    [HttpPost]
    public ActionResult Demographics(DemographicsModel model)
    {
        return this.View(model);
    }
}

在回发时,DemographicsModel填充了正确的类型(我使用MvcContrib来处理抽象类型绑定)。 List<Question>填充了所有正确的数据,包括隐藏字段中每个问题的ID和标题。但是,每个问题中的List<SelectListItem>都设置为null

更新1

问题肯定发生,因为字段未正确命名。例如,“item”字段名称的生成方式如下:

Questions_1__Items_item_Value

当它们看起来真的像这样(添加项目索引并删除错误的“项目”):

Questions_1__Items_1__Value

同样,正在生成字段ID(添加项目索引并删除错误的“项目”):

Questions[1].Items.item.Value

而不是:

Questions[1].Items[0].Value

使用Fiddler并返回正确的ID,模型构建正确,所有单选按钮和复选框都已就位。

3 个答案:

答案 0 :(得分:1)

请尝试以下操作。

ChooseManyQuestionModel.cshtml中,将@Html.EditorFor(m => m.Items)更改为:

@Html.EditorForModel(m => m.Items)

然后,在CheckBoxList.cshtml中,将@model IEnumerable<SelectListItem>更改为:

@model SelectListItem

最后,在每个项目中,修改每个lambda表达式,并将item更改为m,然后删除foreeach循环。这将允许编辑器遍历集合,并为每个元素提供正确的id生成。

答案 1 :(得分:0)

当使用foreach循环时,HTML中生成的ID都是相同的 当使用外观时,使用for循环索引生成的ID,因此正确地发生了绑定,并且在回发后所有数据都可用。

答案 2 :(得分:-1)

在这种情况下,似乎Helper类没有按照您的意愿执行操作。我建议您编写自己的帮助程序类,以便按照您的要求命名输入。