gpt4 book ai didi

razor - 编辑和保存复杂对象

转载 作者:行者123 更新时间:2023-12-04 11:12:58 26 4
gpt4 key购买 nike

假设您有以下对象:

public class Address
{
public String Line1 { get; set; }
public String Line2 { get; set; }
public String City { get; set; }
public String State { get; set; }
public String ZipCode { get; set; }

public Address()
{
}
}

public class Contact
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Telephone { get; set; }

public Address BillingAddress { get; set; }
public List<Address> ShippingAddresses { get; set; }

public Contact()
{
// Assume anything that _could_ be null wouldn't be. I'm excluding
// most "typical" error checking just to keep the examples simple
this.BillingAddress = new Address();
this.ShippingAddresses = new List<Address>();
}
}

假设属性装饰有 [Required] , [Display]和其他属性。

然后我的 Controller (为了演示而简化):
public ActionResult Edit(String id)
{
Contact contact = ContactManager.FindByID(id);
return View(model: contact);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Contact contact)
{
if (ModelState.IsValid) //always fails
{
ContactManager.Save(contact);
return RedirectToAction("Saved");
}
return View(model: contact);
}

我经常看到在 MVC 中编辑这样的对象的演示,但他们不断地将对象的集合分解为自己的形式(例如,编辑联系人,然后编辑联系人的特定地址)。另一方面,我试图在同一页面内编辑所有这些信息,但没有成功。例如:
@model Contact

// simplified for brevity
@using (Html.BeginForm())
{
@Html.LabelFor(x => x.FirstName): @Html.EditorFor(x => x.FirstName)
@Html.LabelFor(x => x.LastName): @Html.EditorFor(x => x.LastName)
@Html.LabelFor(x => x.Telephone): @Html.EditorFor(x => x.Telephone)

<div>
@Html.LabelFor(x => x.BillingAddress.Line1): @Html.EditorFor(x => x.BillingAddress.Line1)
@Html.LabelFor(x => x.BillingAddress.Line2): @Html.EditorFor(x => x.BillingAddress.Line2)
@Html.LabelFor(x => x.BillingAddress.City): @Html.EditorFor(x => x.BillingAddress.City)
@Html.LabelFor(x => x.BillingAddress.State): @Html.EditorFor(x => x.BillingAddress.State)
@Html.LabelFor(x => x.BillingAddress.ZipCode): @Html.EditorFor(x => x.BillingAddress.ZipCode)
</div>

<div>
@foreach (Address addr in Model.ShippingAddresses)
{
<div>
@Html.LabelFor(x => addr.Line1): @Html.EditorFor(x => addr.Line1)
@Html.LabelFor(x => addr.Line2): @Html.EditorFor(x => addr.Line2)
@Html.LabelFor(x => addr.City): @Html.EditorFor(x => addr.City)
@Html.LabelFor(x => addr.State): @Html.EditorFor(x => addr.State)
@Html.LabelFor(x => addr.ZipCode): @Html.EditorFor(x => addr.ZipCode)
</div>
}
</div>
}

我一直遇到的问题是 ModelState.IsValid当我去保存信息时,永远不会过去。这样做有诀窍,还是只是在 MVC 领域之外?我想要一个像 Contact 这样的对象并将所有信息转储在一页上进行编辑,并成功重新保存,但我似乎无法让它工作。 (我的下一步是绑定(bind) ajax,以便您可以在该页面上动态添加/删除“ShipingAddresses”,但我需要先保存才能工作——K.I.S.S)

问题:
  • ModelState.IsValid几乎总是错误的
  • 集合项的表单元素通常具有相同的名称,因此在此演示中每个 Line1ShippingAddresses集合转储到页面为 name="addr_Line1"而不是 ShippingAddresses[0]_Line1就像我期望的那样。
  • 最佳答案

    我猜ModelState.IsValid是错误的,因为您没有正确填充收货地址集合。发生这种情况是因为您没有为输入字段使用正确的名称。看看following article为了更好地理解模型绑定(bind)器希望您的输入字段以什么格式命名,以便能够重新构造值。

    您的代码未生成正确输入名称的原因是因为您使用了这个 foreach 循环,其中 View 丢失了导航上下文的跟踪。

    所以试试这样:

    @for (var i = 0; i < Model.ShippingAddresses.Count; i++)
    {
    <div>
    @Html.LabelFor(x => x.ShippingAddresses[i].Line1):
    @Html.EditorFor(x => x.ShippingAddresses[i].Line1)

    @Html.LabelFor(x => x.ShippingAddresses[i].Line2):
    @Html.EditorFor(x => x.ShippingAddresses[i].Line2)

    @Html.LabelFor(x => x.ShippingAddresses[i].City):
    @Html.EditorFor(x => x.ShippingAddresses[i].City)

    @Html.LabelFor(x => x.ShippingAddresses[i].State):
    @Html.EditorFor(x => x.ShippingAddresses[i].State)

    @Html.LabelFor(x => x.ShippingAddresses[i].ZipCode):
    @Html.EditorFor(x => x.ShippingAddresses[i].ZipCode)
    </div>
    }

    备注:请注意,我还使用 EditorFor 调用替换了您的重复标签,以有效地为这些字段生成输入字段。

    甚至更好地使用这样的编辑器模板:
    @model Contact

    @using (Html.BeginForm())
    {
    @Html.LabelFor(x => x.FirstName):
    @Html.EditorFor(x => x.FirstName)

    @Html.LabelFor(x => x.LastName):
    @Html.EditorFor(x => x.LastName)

    @Html.LabelFor(x => x.Telephone):
    @Html.EditorFor(x => x.Telephone)

    @Html.EditorFor(x => x.BillingAddress)

    @Html.EditorFor(x => x.ShippingAddresses)
    }

    然后定义一个自定义编辑器模板,该模板将自动为 ShippingAddresses 的每个元素呈现集合( ~/Views/Shared/EditorTemplates/Address.cshtml):
    @model Address
    <div>
    @Html.LabelFor(x => x.Line1):
    @Html.EditorFor(x => x.Line1)

    @Html.LabelFor(x => x.Line2):
    @Html.EditorFor(x => x.Line2)

    @Html.LabelFor(x => x.City):
    @Html.EditorFor(x => x.City)

    @Html.LabelFor(x => x.State):
    @Html.EditorFor(x => x.State)

    @Html.LabelFor(x => x.ZipCode):
    @Html.EditorFor(x => x.ZipCode)
    </div>

    现在您不必再担心输入错误的名称了。不仅如此,您还为您的帐单地址和送货地址的集合重复使用地址编辑器模板。它使您的观点更加干燥。

    关于razor - 编辑和保存复杂对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9039336/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com