ASP.NET MVC 3如何在Create视图上为具有ICollection属性的Model提供多字段创建功能

Ken*_*ins 5 entity-framework-4 ef-code-first asp.net-mvc-3

注意:我使用的是MVC3 + Razor,EF4,CF-CTP5

  1. 如何让视图能够在客户端上动态地为每个组织添加多个Address类,并在post上强烈绑定到模型?

  2. 如果(ModelState.IsValid == false),如果输入3个地址并发布无效模型,如何重新填充数字地址及其适当的值,如何在模型中使用视图解析值?

这是我的模特:

public class Organization
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }
    ...
}

public class Address
{
    public int Id { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }
    public int Type { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚如何让组织的创建操作(/组织/创建)像这样处理创建(这样地址和电话号码是提交的模型的一部分):

[HttpPost]
public ActionResult Create(Organization organization)
{
    if (ModelState.IsValid)
    {
        _db.Organizations.Add(organization);
        _db.SaveChanges();
        return RedirectToAction("Details", organization.Id);
    }

    return View(organization);

}
Run Code Online (Sandbox Code Playgroud)

Lor*_*nzo 1

你的问题非常广泛:)这只是实现你的要求的方式之一,我相信有比我更好的方式。

我将从你的第二个问题开始:

如果 (ModelState.IsValid == false),如何让视图解析模型中的值,这样如果您输入 3 个地址并发布无效模型,它会重新填充数字地址及其适当的值?

如果我正确理解你的要求,对我来说这看起来很简单。答案是简单地对您的视图进行编码以呈现模型类内容并将无效模型返回给客户端,就像您在Create操作中所做的那样。

如果您的表单(及其字段)已使用ValidationSummary/ValidationMessagehtml 帮助程序进行修饰,您还将看到验证消息。

  1. 如何允许视图能够在客户端上动态地为每个组织添加多个地址类,并在发布时与模型紧密绑定?

您可以有一个显示组织属性的主视图,然后有另一个显示相关地址的视图。您可以在此处放置一个超链接或一个按钮,打开一个对话框以添加新地址对象,然后在完成后刷新地址列表。同样,您可以将编辑和删除按钮作为列表中的图标。

地址列表是完全在客户端处理的标记,要正确绑定到服务器端 Model 类,应遵守其输入属性的一些简单命名规则。

要使默认模型绑定器类正确绑定您的表单,请为您的Organization类使用以下代码片段

@using (Html.BeginForm()) {
    @Html.HiddenFor(o => o.Id)
    @Html.ValidationSummary( true )
    <fieldset>
        <legend>My Organization</legend>
        <div class="editor-label">@Html.LabelFor( model => model.Name )</div>
        <div class="editor-field">
            @Html.EditorFor( model => model.Name )
            @Html.ValidationMessageFor( model => model.Name )
        </div>
        <br />
        <div id="container">
            <div>Address List</div>
            @foreach (Address a in Model.Addresses ) {
                Html.EditorFor(a);
            }
        </div>
        <div style="text-align:right;margin-top:14px;">
            <input type="submit" id="btnSubmit" value="Save" />
        </div>
    </fieldset>
}
Run Code Online (Sandbox Code Playgroud)

要自动绑定,表单的生成代码应如下所示

<form action="..." id="..." method="post">
    <input type="hidden" name="Id" value="2">
    <input type="hidden" name="Name" value="Acme Corporation">

    <!-- markup for each address -->
    <input type="hidden" name="Addresses[0].Id" value="1">
    <input type="hidden" name="Addresses[0].Line1" value="Line 1">
    <input type="hidden" name="Addresses[0].Line2" value="Line 2">
    ... and so on...
</form>
Run Code Online (Sandbox Code Playgroud)

其属性名为Addresses[index].PropertyName. 如果您在客户端添加新地址,那么这并不重要:只要您的代码遵守此规则,您就可以让默认的 Model Binder 为您完成这项工作。

希望这可以帮助