有人可以解释MVC模型绑定吗?

时间:2013-02-27 16:23:32

标签: asp.net-mvc model-binding

我有一个模型,我创建并传递给我的视图。模型创建一个表单并使用HttpPost属性我得到模型。我将模型保存到数据库然后我想将默认模型状态返回到视图(IE下拉值,但不是所选项目)

我创建了一个空模型,将其传递给视图,但值保持不变,我不明白为什么。

我的观点

 @using (Html.BeginForm())
  {
    @Html.ValidationSummary(true)
    <fieldset>
      <legend>
        <h2>Configuration settings</h2>
      </legend>

      <div class="editor-label">
        @Html.LabelFor(model => model.DeviceType)
      </div>
      <div class="editor-field">
        @Html.DropDownListFor(model => model.DeviceTypeSelectedItem, new SelectList(Model.DeviceType, "Value", "Text"),new {@class = "DeviceTypeDDL"})
        @Html.ValidationMessageFor(model => model.DeviceTypeSelectedItem)
      </div>

       <div class="editor-label">
        @Html.LabelFor(model => model.ConfigGroup)
      </div>
      <div class="editor-field">
        @Html.DropDownListFor(model => model.ConfigGroupSelectedItem, new SelectList(Model.ConfigGroup, "Value", "Text"),new {@class = "ConfigGroupDDL"})
        @Html.ValidationMessageFor(model => model.ConfigGroupSelectedItem)
      </div>

       <div class="editor-label">
        @Html.LabelFor(model => model.ConfigName)
      </div>
      <div class="editor-field">
        @Html.DropDownListFor(model => model.ConfigNameSelectedItem, new SelectList(Model.ConfigName, "Value", "Text"),new {@class = "ConfigNameDDL"})
        @Html.ValidationMessageFor(model => model.ConfigNameSelectedItem)
      </div>

        <div class="editor-label">
        @Html.LabelFor(model => model.ConfigValue)
      </div>
      <div class="editor-field">
        @Html.EditorFor(model => model.ConfigValue)
        @Html.ValidationMessageFor(model => model.ConfigValue)
      </div>

        <div class="editor-label">
        @Html.LabelFor(model => model.MergeOrDelete)
      </div>
      <div class="editor-field">
        @Html.DropDownListFor(model => model.MergeOrDeleteSelectedItem, new SelectList(Model.MergeOrDelete, "Value", "Text"), new { @class = "MergeDeleteDDL" })
        @Html.ValidationMessageFor(model => model.MergeOrDeleteSelectedItem)
      </div>

      @Html.HiddenFor(model => model.ManagementGroupId)

      <p>
        <input type="submit" value="Add" />
      </p>
    </fieldset>
  }

控制器:

[HttpGet]
    public ActionResult Index(int id)
    {
      var model = CreateDefaultConfigModel(id);
      return View(model);
    }
    [HttpPost]
    public ActionResult Index(vmConfiguration model)
    {
      if (ModelState.IsValid)
      {
        bool isMerge = model.MergeOrDeleteSelectedItem == 1 ? true : false;
        _configLogic.AddConfigurationValue((int)model.ConfigNameSelectedItem, (int)model.ManagementGroupId, model.ConfigValue, isMerge);
        return View(CreateDefaultConfigModel(model.ManagementGroupId));
      }
      else
      {
        return View(model);
      }
    }
private vmConfiguration CreateDefaultConfigModel(int id)
{
  var model = new vmConfiguration
  {
    DeviceType = _configLogic.GetDevices,
    ConfigGroup = new List<SelectListItem>() { EmptySelect() },
    ConfigName = new List<SelectListItem>() { EmptySelect() },
    ConfigGroupSelectedItem = null,
    MergeOrDeleteSelectedItem = null,
    DeviceTypeSelectedItem = null,
    ConfigNameSelectedItem = null,
    ManagementGroupId = id,
    ParamData = _configLogic.GetParamValuesForGroup(id)
  };
  return model;
}
private static SelectListItem EmptySelect()
{
  return new SelectListItem { Text = "No value", Value = "-1" };
}
private ConfigurationLogic _configLogic;

做研究我发现如果我在创建新模型之前调用this.ModelState.Clear();然后它可以工作,但为什么MVC会忽略我传递的模型并使用绑定的模型?

1 个答案:

答案 0 :(得分:3)

变化

return View(CreateDefaultConfigModel(model.ManagementGroupId));

到这个

return RedirectToAction("Index", new { id = model.ManagementGroupId });

它不会忽略您的模型,它会在您将表单发送回同一个索引页面时尝试填写表单,因为它假设您由于需要更多信息而将其发送回来,并且它试图通过不强制执行用户再次重新输入所有信息。此信息全部存储在ModelState中,因为它包含已发布回服务器的尝试值。无论如何,在成功发布后重定向是推荐的模式。查找PRG pattern