注意:我正在使用 MVC3 + Razor,EF4,CF-CTP5
如何让视图能够在客户端上动态地为每个组织添加多个地址类,并在帖子上强烈绑定到模型?
如果(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; }
}
我正在试图弄清楚如何让组织(/组织/创建)的创建操作处理创建(如此地址和电话号码是提交模型的一部分):
[HttpPost]
public ActionResult Create(Organization organization)
{
if (ModelState.IsValid)
{
_db.Organizations.Add(organization);
_db.SaveChanges();
return RedirectToAction("Details", organization.Id);
}
return View(organization);
}
答案 0 :(得分:1)
你的问题很有趣:) 这只是您的要求之一,我相信有比我更好的方式。
我将从你的第二个问题开始:
如何使用视图解析值 在模型中如果 (ModelState.IsValid == false)这样的 如果您输入3个地址并发布 一个无效的模型,它重新填充 号码地址和他们的 适当的价值观?
如果我正确理解您的请求,对我来说看起来很简单。答案就是 编码您的视图以呈现模型类内容 ,并将无效模型返回到客户端,就像您在Create
操作中一样。< / p>
如果您的表单(及其字段)已使用ValidationSummary/ValidationMessage
html帮助程序进行修饰,您还将看到验证消息。
- 如何让视图能够添加多个地址 每个组织的类动态 在客户端,并强烈约束 帖子上的模型?
醇>
您可以拥有一个显示组织属性的主视图,然后有另一个显示相关地址的视图。在这里,您可以放置一个超链接或按钮,打开一个对话框以添加新的地址对象,然后在完成后刷新地址列表。同样,您可以在列表中编辑和删除按钮作为图标。
地址列表是在客户端完全处理的一个标记,要正确绑定到服务器端,Model类应该遵循一些简单的命名规则来获取它的输入属性。
要使默认模型Binder类正确绑定您的表单,请使用以下代码段为您的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>
}
要自动绑定,表单的结果代码应如下所示
<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>
将其属性命名为Addresses[index].PropertyName
。
如果您在客户端上添加新地址,那么这并不重要:只要您的代码遵守此规则,您就可以使用默认的Model Binder为您完成工作。
希望这有帮助
答案 1 :(得分:0)
我不确定我是否正确理解了您的问题,但就问题1而言,我认为您正在寻找一个ViewModel。像这样或许..
OrganizationViewModel.cs
public class OrganizationViewModel
{
public OrganizationViewModel(Organization org, IList<Address> addresses)
{
this.Organization = org;
this.Addresses = addresses
}
public Organization Organization {get;set;}
public IList<Address> Addresses {get;set;}
}
OrganizationController.cs
public class OrganizationController : Controller
{
private readonly IOrganizationService _organizationService: //or whatever method you use
public OrganizationController(IOrganizationService orgService)
{
this._organizationService = orgService;
}
public ActionResult Item(int id)
{
var org = _organizationService.GetOrganizationById(id);
var addresses = _organizationService.GetOrgAddressesByOrgId(id);
return View(new OrganizationViewModel(program, addresses));
}
}
Item.cshtml
@model OrganizationViewModel
<h1>@Model.Organization.Name</h1>
<ul>
@foreach(var a in Model.Addresses)
{
<li>@a.Line1</li>
<li>@a.Line2</li>}
</ul>
在我尝试回答2号之前,你应该说明我是否正确理解问题1.希望这会有所帮助。
答案 2 :(得分:0)
我设法使用LINQ to SQL执行此操作。现在我正在尝试使用实体框架,但它确实使一切变得更加复杂。所以我没有为您提供解决方案,但也许我的L2S解决方案可能有所帮助?
使用从我的数据库生成的模型,我可以在我看来这样做:
@for (int i = 0; i < Model.Contact.EmailAddresses.Count; ++i)
{
<li>
@Html.TextBoxFor(x => x.Contact.EmailAddresses[i].EmailAddress)
@Html.HiddenFor(x => x.Contact.EmailAddresses[i].EmailAddressID)
</li>
}
我有一个视图模型类:
class ContactViewModel
{
Contact contact { get; set; }
}
这很好用,在我的控制器操作中,我得到了我的Contact对象,其中的Contact.ContactEmailAddresses列表就像我预期的那样填充。
但是对于EF,我不能再使用从数据库生成的EmailAddresses属性上的[i]。我想出的最好的是:
@Html.TextBox("Contact.EmailAddresses[" + i + "].EmailAddress", Model.Contact.EmailAddresses.ElementAt(i).EmailAddress)