【问题标题】:MVC Posting Form with Partial views returns Null Model具有部分视图的 MVC 发布表单返回 Null 模型
【发布时间】:2016-03-08 01:19:55
【问题描述】:

我已经阅读了多篇关于同一问题的帖子,似乎共识是使用子模型对象和编辑器模板。我没有重构我的代码来做到这一点,我仍然收到一个空模型返回。我不知道我哪里错了。这是我的概念验证代码:

控制器:

[HttpPost]
    public ActionResult CreateNewMatter(NewMatterModel model)
    {
        WorkflowRepository repo = new WorkflowRepository();
        repo.SaveNewMatterWorkflow(model.NewMatterIndex.ClientCode, model.NewMatterIndex.ClientName, model.NewMatterIndex.MatterCode, model.NewMatterIndex.MatterName);

        return View();
    }

主视图:

@model NBI_Flow.Web.Models.ActionModels.NewMatterModel

@{
    ViewBag.Title = "Create New Matter";
}

<div class="screen-container">
    @using (Html.BeginForm("CreateNewMatter", "Action", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <div id="top-control-panel">
            <div id="button-row">
                <input type="button" id="home-button" value="Home" onclick="location.href = '@Url.Action("Index", "Home")'; return false;" />
                <input type="submit" id="save-button" value="Save" />
                <input type="button" id="delete-button" value="Delete" onclick="location.href = '@Url.Action("Index", "Home")'; return false;" />
                <input type="button" id="submit-button" value="Submit" onclick="saveNewMatter();" />
            </div>
            <div id="status-row">
                <div class="status-block">
                    <label><span>Request Number:</span>013603</label><br />
                    <label><span>Request Status:</span>01. Draft</label><br />
                    <label><span>Client #:</span>27619</label>
                </div>
                <div class="status-block">
                    <label><span>Request Type:</span>Existing Client</label><br />
                    <label><span>Created On:</span>02/29/2016 09:43:10 AM</label><br />
                    <label><span>Client Name:</span>Greenfield Partner LLC</label>
                </div>
                <div class="status-block">
                    <label><span>Primary Billing Partner:</span></label><br />
                    <label><span>Created By:</span>Brian Legg</label><br />
                    <label><span>BABAC Partner:</span></label>
                </div>
            </div>
        </div>
    
        @Html.Hidden("SuccessUrl", Url.Action("Index", "Home"))
        
        <div id="new-matter-container">
            <ul>
                <li><a href="#tab0" id="_tab0">Intro</a></li>
                <li><a href="#tab1" id="_tab1">Matter Details</a></li>
                <li><a href="#tab2" id="_tab2">BABAC</a></li>
                <li id="tab3tab"><a href="#tab3" id="_tab3">Client Relationship</a></li>
                <li><a href="#tab4" id="_tab4">Risk Management</a></li>
                <li><a href="#tab5" id="_tab5">Relevant Parties/Conflicts</a></li>
                <li><a href="#tab6" id="_tab6">Attachments</a></li>
                <li><a href="#tab7" id="_tab7">Comments</a></li>
                <li><a href="#tab8" id="_tab8">Audit</a></li>
                <li><a href="#tab9" id="_tab9">Copy Request</a></li>
                <li><a href="#tab10" id="_tab10">Proxies</a></li>
            </ul>
            <div id="tab0">
                @Html.EditorFor(model => model.NewMatterIndex)
            </div>
            <div id="tab1">
                @Html.Partial("_MatterDetails")
            </div>
            <div id="tab2">
                @Html.Partial("_BABAC")
            </div>
            <div id="tab3">
                @Html.Partial("_ClientRelationship")
            </div>
            <div id="tab4">
                @Html.Partial("_RiskManagement")
            </div>
            <div id="tab5">
                @Html.Partial("_RelevantParties")
            </div>
            <div id="tab6">
                @Html.Partial("_Attachments")
            </div>
            <div id="tab7">
                @Html.Partial("_Comments")
            </div>
            <div id="tab8">
                @Html.Partial("_Audit")
            </div>
            <div id="tab9">
                @Html.Partial("_CopyRequest")
            </div>
            <div id="tab10">
                @Html.Partial("_Proxies")
            </div>
        </div>
    }
</div>

我知道那里有很多部分,但我只关心第一个 EditorFor。一旦它工作,我会将其余部分转换为 EditorTemplates。

EditorTemplate(部分):

@model NBI_Flow.Web.Models.ActionModels.NewMatterIndex

<div id="intro-section">

    <label>Requesting Attorney:</label>
    <select id="attorney-list">
        <option value="0">Select...</option>
        <option value="1">Abramowitz, Laurie</option>
        <option value="2">Adivari, Heather</option>
        <option value="3">Adler, Sara</option>
        <option value="4">Ainsztein, Zachary</option>
        <option value="5">Allardyce, Aaron L</option>
        <option value="6">Alten, Klaus</option>
        <option value="7">Alvarado, Daniela</option>
        <option value="8">Alyonycheva, Tatiana N</option>
    </select>

    <br /><br />

    <label>Please enter the matter name:</label>
    <input type="text" id="matterName" />

    <br /><br />

    @* 100% throw away code *@

    <label>Please enter the client code:</label>
    @*<input type="text" id="clientCode" />*@
    @Html.TextBoxFor(m => Model.ClientCode)
  ..........

这是我要发布的“Model.ClientCode”。当我点击提交按钮时,我发布的模型如下所示:

非常感谢任何帮助。如果我遗漏了一些重要的数据,请告诉我。谢谢!

【问题讨论】:

  • 如果你想使用部分,那么你需要将HtmlFieldPrefix 传递给部分(参考this answer),但是为每个嵌套模型使用EditorTemplate 会自动执行此操作

标签: c# asp.net-mvc asp.net-mvc-5


【解决方案1】:

使用编辑器模板从来都不是必需的。我不确定你从哪里得到这个建议,但应该持保留态度。问题的核心归结为分配给您的输入/选择/等的name 属性。元素以及 modelbinder 期望该名称在 POST 上的名称。

对于此处的示例,要绑定 ClientCode,modelbinder 需要一个名为 NewMatterIndex.ClientCode 的 post 值。如果是其他内容,例如 ClientCode,那么 modelbinder 将丢弃该值。

现在,在处理部分(编辑器模板是其中的一种形式)时,一切都与上下文有关。在局部视图中,上下文是该局部视图的模型,重要的是,不是主视图的模型。因此,例如,如果您将 Model.NewMatterIndex 作为模型传递给一个局部,那么这就是 Razor 在渲染该局部时所具有的所有上下文。因此,如果您随后执行以下操作:

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

在该部分内部,生成的名称属性将只是 ClientCode,而不是需要的 NewMatterIndex.ClientCode

编辑器模板只是在EditorFor 维护一些父上下文方面的部分解决方案。当你打电话时:

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

它将正确地为内部呈现的每个输入添加前缀NewMatterIndex.。这不能保证名称总是正确的,因为可能存在其他问题。但是,在这种特定情况下,它将解决问题。您仍然遇到问题的原因可能是由于您的编辑器模板中的拼写错误。你有:

@Html.EditorFor(m => Model.ClientCode)

应该是这样的:

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

它们看起来很相似,但实际上意味着非常不同的东西。此外,虽然您的问题围绕这一特定属性得到解决,但您似乎都在为所有其他输入手动创建 HTML 并且 没有为它们中的任何一个分配名称属性。没有名称,值甚至不会被发布,更不用说绑定到任何东西了。

【讨论】:

  • 感谢您的深入解答!我确实意识到所有其他属性都不受约束。这是一个概念验证,正在慢慢成为一个可行的项目。因此,一旦我获得 1 个属性以成功绑定,我将绑定所有这些。至于解决方案....我尝试更改为“@Html.TextBoxFor(m => m.ClientCode)”,但仍然得到相同的结果。代码仍在运行,但我在发布时得到一个空值。我会根据你的 cmets 继续尝试。谢谢
  • 无视!它现在可以工作了,我只是在测试它时做了一些愚蠢的事情。非常感谢。标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
相关资源
最近更新 更多