单个属性没有绑定在HttpPost上

时间:2012-08-28 20:42:14

标签: asp.net-mvc-3 c#-4.0

我正在为我们公司的第一个MVC3项目工作,而且我遇到了障碍。没有人能够弄清楚发生了什么。

我在页面上使用了一个复杂的模型:

public class SpaceModels : List<SpaceModel> {
    public bool HideValidation { get; set; }
    [Required(ErrorMessage=Utilities.EffectiveDate + Utilities.NotBlank)]
    public DateTime EffectiveDate { get; set; }

    public bool DisplayEffectiveDate { get; set; }
}

在Controller中,我创建了一个SpaceModels对象,其中包含空格SpaceModel,用于组合Spaces时(这将是目标空间)。

// Need a list of the models for the View.
SpaceModels models = new SpaceModels();
models.EffectiveDate = DateTime.Now.Date;
models.DisplayEffectiveDate = true;
models.Add(new SpaceModel { StoreID = storeID, SiteID = siteID, IsActive = true });

        return View("CombineSpaces", models);

然后在View中,我使用SpaceModels对象作为模型,并在为生效日期创建TextBox的表单中:

@model Data.SpaceModels

@using (Html.BeginForm("CombineSpaces", "Space")) {
    <div class="EditLine">
        <span class="EditLabel LongText">
            New Space Open Date
        </span>
        @Html.TextBoxFor(m => m.EffectiveDate, new {
                        size = "20",
                        @class = "datecontrol",
                        // Make this as a nullable DateTime for Display purposes so we don't start the Calendar at 1/1/0000.
                        @Value = Utilities.ToStringOrDefault(Model.EffectiveDate == DateTime.MinValue ? null : (DateTime?)Model.EffectiveDate, "MM/dd/yyyy", string.Empty)
        })
        @Html.ValidationMessageFor(m => m.EffectiveDate)
    </div>

    <hr />        

    Html.RenderPartial("_SpaceEntry", Model);
}

渲染的局部视图遍历所有SpaceModel,并创建一个包含各个SpaceModel对象的Edit字段。 (我正在使用List来使用相同的视图,以便空间被细分时。)

然后在HttpPost上,EffectiveDate仍然返回它的DateTime.MinValue默认值:

[HttpPost]
public ActionResult CombineSpaces(SpaceModels model, long siteID, long storeID, DateTime? effectiveDate) {
// processing code
}

我添加了DateTime? effectiveDate参数证明当它被改变时的值确实会回来。我甚至尝试将TextBox的渲染移动到_SpaceEntry Partial View中,但也没有任何效果。

我也尝试使用@Html.EditorFor(m => m.EffectiveDate)代替@Html.TextBoxFor(),但仍返回DateTime.MinValue。 (顺便说一句,我的老板不喜欢放弃使用@Html.EditorForModel进行渲染的控制。)

我必须要有一些简单的东西。如果您还有其他需要,请告诉我。

2 个答案:

答案 0 :(得分:1)

查看DefaultModelBinder的{​​{3}},特别是BindComplexModel(),如果它检测到集合类型,它将绑定各个元素,但不会尝试绑定列表对象本身的属性。

答案 1 :(得分:1)

模型绑定的作用是尝试将视图中的事物或元素的名称与模型中的属性或操作方法中的参数进行匹配。您不必传递所有这些参数,您只需将它们添加到视图模型中,然后在操作方法中调用TryUpdateModel即可。我不确定你要用SpaceModel或List做什么,但我没有看到需要从List继承。我相信你有充分的理由这样做。我就是这样做的。

视图模型

public class SpacesViewModel
{
    public DateTime? EffectiveDate { get; set; }
    public bool DisplayEffectiveDate { get; set; }
    public List<SpaceModel> SpaceModels { get; set; }
}

GET行动方法

[ActionName("_SpaceEntry")]
public PartialViewResult SpaceEntry()
{
    var spaceModels = new List<SpaceModel>();
    spaceModels.Add(
        new SpaceModel { StoreID = storeID, SiteID = siteID, IsActive = true });

    var spacesVm = new SpacesViewModel
    {
        EffectiveDate = DateTime.Now,
        DisplayEffectiveDate = true,
        SpaceModels = spaceModels
    };

    return PartialView("_SpaceEntry", spacesVm);
}

POST动作方法

[HttpPost]
public ActionResult CombineSpaces() 
{
    var spacesVm = new SpacesViewModel();

    // this forces model binding and calls ModelState.IsValid 
    // and returns true if the model is Valid
    if (TryUpdateModel(spacesVm))
    {
        // process your data here
    }
    return RedirectToAction("Index", "Home");
}

视图

<label>Effective date: </label>
@Html.TextBox("EffectiveDate", Model.EffectiveDate.HasValue ?
    Model.EffectiveDate.Value.ToString("MM/dd/yyyy") : string.empty, 
    new { @class = "datecontrol" })

有时您需要使用隐藏字段(如

)显式绑定表单数据
@Html.HiddenField("EffectiveDate", Model.EfectiveDate.)

为了绑定SpaceModel对象的属性,您可以将单个属性(如SiteID)添加到视图模型,或为单个SpaceModel添加SpaceModel属性。如果要成功绑定复杂模型,请将其添加为填充了键值对而不是List的Dictionary。然后,您应该将字典添加到视图模型中。您甚至可以为分层数据添加词典字典。

我希望这会有所帮助:)