MVC-binder无法在表单提交

时间:2016-10-05 09:42:58

标签: c# asp.net-mvc razor model-binding

我正在使用Umbraco MVC构建我们网页的四个表单。 我有一个ViewModel,它实际上是另一个ViewModel的属性,并使用下面的razor-form中的部分视图填充。无论出于何种原因,子视图模型(RequiredHealthInputData,se below)在绑定后始终为null!绑定器将成功将所有表单值绑定到我的主视图模型,但我的子视图模型将保持为null!

(我已经研究了很多关于复杂类型绑定的类似问题,但我相信但到目前为止我找不到任何解决方案(前缀,重命名我的属性以支持路由等)。

我有一个PtjInsurancePickerViewModel.cs(主视图模型),如下所示:

public class PtjInsurancePickerViewModel : BaseViewModel, IValidatableObject
{
    [Required]
    public string InsuranceNameStr { get; set; } = "-1";

    public HealthDeclarationModel RequiredHealthInputData { get; set; }
}

HealthDeclarationModel也是一个ViewModel,具有以下值:

public class HealthDeclarationModel : BaseViewModel, IValidatableObject
{
    [Display(Name = "Extra comment")]
    public string ExtraComments { get; set; }

    [Display(Name = "EnsurancePTName")]
    public string EnsurancePTName { get; set; }
}

我有一个使用以下形式的InsurancePicker.cshtml视图:

@using (Html.BeginUmbracoForm<InsurancePickerSurfaceController>("ProcessSelections"))
{
    <h3>Select insurance</h3>
    @Html.Partial("../Partials/InsurancePicker/_vsFamilyInsuranceProtection", Model)

    <h3>Select extra options</h3>
    @Html.Partial("../Partials/_Healthdeclaration", Model.RequiredHealthInputData)

    <h3>Send!</h3>
    <input type="submit" class="btn btn-success" value="Send!" title="Confirm choices"/>
}

请注意,表单由两个部分组成,一个获取PtjInsurancePickerViewModel,另一个获取HealthDeclarationModel,这是PtjInsurancePickerViewModel的属性

以下是我的HealthDeclarationModel的部分内容:

        <div class="HealthDeclarationModel-Panel">

            <strong>2. Är du fullt arbetsför?</strong>
            @Html.DropDownListFor(x => x.EnsurancePTName, Model.YesNoLista, new { @class = "form-control", @id = "EnsurancePTNameSelect" })
            @Html.ValidationMessageFor(x => x.EnsurancePTName)


            @Html.TextAreaFor(x => x.ExtraComments, new { @class = "form-control", style = "max-width:100%; min-width: 100%;" })
            @Html.ValidationMessageFor(x => x.ExtraComments)

        </div>

(注意:我在部分特殊ID中给出了输入字段(由jquery用于statemanagement)。也许这可能是问题的一部分?我尝试使用带有模型名称前缀的ID提交&# 34; HealthDeclarationModel .EnsurancePTNameSelect&#34;而不仅仅是&#34; EnsurancePTNameSelect&#34;例如,但无效)

提交功能导致以下方法:

[Authorize(Roles = "Forsakrad")]
public class InsurancePickerSurfaceController : BaseSurfaceController
{

    [HttpPost]
    public ActionResult ProcessSelections(PtjInsurancePickerViewModel filledModel)
    {
        //Checks if the very important RequiredHealthInputData submodel is null

        if (filledModel.RequiredHealthInputData == null)
        {
            throw new ApplicationException("Critical data missing!!");
        }
        else
        {
            DoImportantStuffWithRequiredHealthInputData(filledModel.RequiredHealthInputData)
        }

        return CurrentUmbracoPage();
    }
}

现在这是我的问题。 RequiredHealthInputData将始终为null,因为MVC绑定器无法将HealthDeclarationModel绑定到PtjInsurancePickerViewModel。 默认活页夹的结果如下所示:

    {IndividWebb.Models.PtjInsurancePickerViewModel}
       InsuranceNameStr: "0"
       HalsodeklarationDataModel: null

但是,表单集合看起来像这样:

    controllerContext.HttpContext.Request.Form.AllKeys
    {string[17]}
       [2]: "InsuranceNameStr"
       [9]: "EnsurancePTName"
       [12]: "ExtraComments"
        14]: "HalsodeklarationDataModel"

    (Some results have been excluded)

另请注意,EnsurancePTName是属于HalsodeklarationDataModel的输入,其ID为EnsurancePTName而不是HalsodeklarationDataModel.EnsurancePTName。

我真的不知道如何继续这个,甚至不知道如何调试它。 我只是一个定制的助手来验证绑定确实排除了HalsodeklarationDataModel的所有值

2 个答案:

答案 0 :(得分:1)

不绑定的原因是因为您使用@Html.Partial("../Partials/_Healthdeclaration", Model.RequiredHealthInputData)生成的表单控件具有与name无关的PtjInsurancePickerViewModel属性,例如,它生成

<textarea name="ExtraComments" ....>

需要的地方

<textarea name="RequiredHealthInputData.ExtraComments" ....>

一种选择是将HtmlFieldPrefix传递给部分AdditionalViewData

@Html.Partial("../Partials/_Healthdeclaration", Model.RequiredHealthInputData, 
new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "RequiredHealthInputData" }})

另请参阅getting the values from a nested complex object that is passed to a partial view,其中包含HtmlHelper扩展方法的代码,以简化此操作。

然而,首选方法是使用EditorTemplate。将您的部分重命名为HealthDeclarationModel.cshtml(即匹配类的名称)并将其移至/Views/Shared/EditorTemplates文件夹(或/Views/yourControllerName/EditorTemplates文件夹),然后在视图中使用

@Html.EditorFor(m => m.RequiredHealthInputData)

将生成正确的name属性。

答案 1 :(得分:0)

更改_Healthdeclaration视图,使其使用PtjInsurancePickerViewModel作为视图模型。简而言之,将相同的模型传递给所有部分,以确保输入名称正确。