繁体   English   中英

在部分null异常内的部分

[英]Partial within a partial null exception

我有一个MVC表格,它使用三个模型比其他所有表格都要复杂。

Company -> Base_IP -> RequestedIPViewModel -> Partial1 -> Partial2 Company -> Base_IP -> RequestedIP ViewModel -> Partial1 -> Partial2

我正在使用BeginCollectionItem,因为每个模型都有一个模型的属性列表。 IE-Company有一个名为baseIps的属性,BaseIp类有一个名为requestIps的属性, requestedIps返回的是null,计数在页面渲染中,但不在提交中。

post Create()中提交数据库时,我在'requestedIps'属性上得到了null,这是为什么呢?

我在下面添加了有问题的控制器和部分代码示例,而不是全部,因为它非常庞大/多余-如有任何问题,请告诉我。

控制器- [HttpGet] Create()

public ActionResult Create()
        {
            var cmp = new Company
            {
               contacts = new List<Contact>
                {
                    new Contact { email = "", name = "", telephone = "" }
                }, pa_ipv4s = new List<Pa_Ipv4>
                {
                    new Pa_Ipv4 
                    { 
                        ipType = "Pa_IPv4", registedAddress = false, existingNotes = "", numberOfAddresses = 0, returnedAddressSpace = false, additionalInformation = "",
                        requestedIps = new List<IpAllocation>
                        {
                            new IpAllocation { allocationType = "Requested", cidr = "", mask = "", subnet  = "" }
                        }
                    }
                }
            };
            return View(cmp);
        }

控制器- [HttpPost] Create()

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Company cmp) // does not contain properties assigned/added to in view render
        {
            if (ModelState.IsValid)
            {
                db.companys.Add(cmp);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(cmp);
        }

建立检视

@model Company
@using (Html.BeginForm())
{
            <div id="editorRowsAsn">
                @foreach (var ip in Model.pa_ipv4s)
                {
                    @Html.Partial("Pa_IPv4View", ip)
                }
            </div>
            <br />
            <div data-role="main" class="ui-content">
                <div data-role="controlgroup" data-type="horizontal">
                    <input type="submit" class="ui-btn" value="Create" />
                </div>
            </div>
}

Pa_Ipv4视图

@model Pa_Ipv4
@using (Html.BeginCollectionItem("pa_ipv4s"))
{
    @Html.AntiForgeryToken()

    <div id="editorRowsRIpM">
        @foreach (var item in Model.requestedIps)
        {
            @Html.Partial("RequestedIpView", item)
        }
    </div>
    @Html.ActionLink("Add", "RequestedManager", null, new { id = "addItemRIpM", @class = "button" }

}

RequestedIpView

@model IpAllocation
<div class="editorRow">
    @using (Html.BeginCollectionItem("requestedIps"))
    {
        <div class="ui-grid-c ui-responsive">
            <div class="ui-block-a">
                <span>
                    @Html.TextBoxFor(m => m.subnet, new { @class = "checkFiller" })
                </span>
            </div>
            <div class="ui-block-b">
                <span>
                    @Html.TextBoxFor(m => m.cidr, new { @class = "checkFiller" })
                </span>
            </div>
            <div class="ui-block-c">
                <span>
                    @Html.TextBoxFor(m => m.mask, new { @class = "checkFiller" })
                    <span class="dltBtn">
                        <a href="#" class="deleteRow"><img src="~/Images/DeleteRed.png" style="width: 15px; height: 15px;" /></a>
                    </span>
                </span>
            </div>
        </div>
    }
</div>

例如,您的第一个(外部)局部将生成与您的模型相关的正确名称属性(您的代码在Pa_Ipv4.cshtml视图中未显示任何控件,但我认为您确实有一些控件),例如

<input name="pa_ipv4s[xxx-xxx].someProperty ...>

但是内部部分不会因为@using (Html.BeginCollectionItem("requestedIps"))会生成

<input name="requestedIps[xxx-xxx].subnet ...>
<input name="requestedIps[xxx-xxx].cidr ...>

他们应该在哪里

<input name="pa_ipv4s[xxx-xxx].requestedIps[yyy-yyy].subnet ...>
<input name="pa_ipv4s[xxx-xxx].requestedIps[yyy-yyy].cidr ...>

通常,您可以使用其他视图数据将前缀传递给局部视图(例如,请参考此答案 ),但不幸的是,您无权访问BeginCollectionItem帮助程序生成的Guid ,因此无法正确为name属性添加前缀。

此处此处的文章讨论了创建自己的用于处理嵌套集合的助手。

其他选项包括使用嵌套的for循环以及包括集合索引器的隐藏输入,这将允许您从集合中删除项目,并且在提交表单时仍能够绑定到模型。

for (int i = 0; i < Model.pa_ipv4s.Count; i++)
{
  for(int j = 0; j < Model.pa_ipv4s[i].requestedIps.Count; j++)
  {
    var name = String.Format("pa_ipv4s[{0}].requestedIps.Index", i);
    @Html.TextBoxFor(m => m.pa_ipv4s[i].requestedIps[j].subnet)
    @Html.TextBoxFor(m => m.pa_ipv4s[i].requestedIps[j].cidr)
    ...
    <input type="hidden" name="@name" value="@j" />
  }
}

但是,如果您还需要动态添加新项目,则需要使用javascript生成html(请参阅此处此处的示例)

如果您查看最终的标记,则可能会有名称如下的输入

input name="subnet" 
input name="cidr" 
input name="mask" 

这是表单收集后表单集合的显示方式。 不幸的是,这不会绑定到您的公司模型。

您的字段将需要看起来像这样

input name="Company.pa_ipv4s[0].subnet"
input name="Company.pa_ipv4s[0].cidr"
input name="Company.pa_ipv4s[0].mask"

input name="Company.pa_ipv4s[1].subnet"
input name="Company.pa_ipv4s[1].cidr"
input name="Company.pa_ipv4s[1].mask"

有多种方法可以“修复”此问题,每种方法都有其自己的警告。

一种方法是设置“编辑器”视图(通常在〜/ Views / Shared / EditorTemplates / ClassName .cshtml中),然后使用@ Html.EditorFor(x => x.SomeEnumerable)。 在您需要能够从集合中间删除任意项目的情况下,这将无法正常工作。 尽管您仍然可以通过设置的额外属性(例如ItemIsDeleted来处理这些情况(例如,通过javascript)。

在这里设置一个完整的示例很冗长,但是您也可以参考本教程: http : //coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/

首先,您将创建一个简单的模板,例如

~/Views/Share/EditorTemplates/Contact.cshtml

 @model yournamespace.Contact
 <div>
     @Html.LabelFor(c => c.Name)
     @Html.TextBoxFor(c => c.Name)
     @Html.ValidationMessageFor(c => c.Name)
</div>
<div>
     @Html.LabelFor(c => c.Email)
     @Html.TextBoxFor(c => c.Email)
     @Html.ValidationMessageFor(c => c.Email)
</div>
... other simple non-enumerable properties of `Contact` ...
@Html.EditorFor(c => c.pa_ipv4s) @* uses ~/Views/Shared/EditorTemplates/pa_ipv4s.cshtml *@

在编辑/创建Company视图中,您可以将其调用为

@Html.EditorFor(company => company.Contacts)

(就像Company的EditorTemplate会调用EditorFor pa_ipv4s。)

当您以这种方式使用EditorFor时,MVC将为您自动处理索引。 (在这里,如何处理添加新联系人/ IPv4 / etc的方法要高级一些,但这应该可以帮助您入门。)


MVCContrib也有一些可用于此目的的辅助方法,但是从我记得的情况来看,它并不是特别简单,并且可能将您绑定到特定的MVC版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM