Rob*_*urd 6 asp.net-mvc razor asp.net-mvc-4 asp.net-mvc-viewmodel
我通过表单HttpPost将ViewModel从我的View传递回Controller.但是,返回的值始终为NULL.
视图模型
public class vmCompanyAddress
{
public StatelyTechAdmin.Models.Company Company { get; set; }
public StatelyTechAdmin.Models.CompanyAddress Address { get; set; }
public SelectList Counties { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
公司类模型
public class Company
{
[Key]
public virtual long CompanyId { get; set; }
[Required]
[Display(Name = "Company Name")]
public virtual string Name { get; set; }
public virtual DateTime CreatedDate { get; set; }
public virtual IEnumerable<CompanyAddress> CompanyAddresses { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
CompanyAddress类模型
public class CompanyAddress
{
[Key]
public virtual long CompanyAddressId { get; set; }
[Required]
public virtual long CompanyId { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[Required]
public virtual int CopmanyAddressTypeId { get; set; }
[ForeignKey("CopmanyAddressTypeId")]
public virtual CompanyAddressType CompanyAddressType { get; set; }
[Display(Name = "Address 1")]
public virtual string Address1 { get; set; }
[Display(Name = "Address 2")]
public virtual string Address2 {get; set; }
[Display(Name = "Town")]
public virtual string Town { get; set; }
[Display(Name = "City")]
public virtual string City { get; set; }
[Required]
public virtual long CountyId { get; set; }
[ForeignKey("CountyId")]
[Display(Name = "County")]
public virtual County County { get; set; }
[Required]
[Display(Name = "Postal Code")]
public virtual string PostalCode { get; set; }
public virtual DateTime CreatedDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
控制器(获取):
// GET: /Company/Create
public ActionResult Create()
{
vmCompanyAddress vm = new vmCompanyAddress();
vm.Counties = new SelectList(db.County, "CountyId", "Name", -1);
//vm.Address = new CompanyAddress();
//vm.Company = new Company();
return View(vm);
}
Run Code Online (Sandbox Code Playgroud)
控制员(职位):
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(vmCompanyAddress company)
{
if (ModelState.IsValid)
{
db.Companies.Add(company.Company);
//Amend Address Company & Address Type before save to DB
company.Address.CompanyId = company.Company.CompanyId;
company.Address.CopmanyAddressTypeId = 1;
db.CompanyAddress.Add(company.Address);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(company);
}
Run Code Online (Sandbox Code Playgroud)
查看(创建)
@model StatelyTechAdmin.ViewModels.vmCompanyAddress
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Company</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Company.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Company.Name)
@Html.ValidationMessageFor(model => model.Company.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Company.CreatedDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Company.CreatedDate)
@Html.ValidationMessageFor(model => model.Company.CreatedDate)
</div>
@* Invoice Address *@
<div class="editor-label">
@Html.LabelFor(model => model.Address.Address1)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address.Address1)
@Html.ValidationMessageFor(model => model.Address.Address1)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Address.Address2)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address.Address2)
@Html.ValidationMessageFor(model => model.Address.Address2)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Address.Town)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address.Town)
@Html.ValidationMessageFor(model => model.Address.Town)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Address.City)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address.City)
@Html.ValidationMessageFor(model => model.Address.City)
</div>
@*<div class="editor-label">
@Html.LabelFor(model => model.Address.County)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Address.CountyId, Model.Counties)
</div>*@
<div class="editor-label">
@Html.LabelFor(model => model.Address.PostalCode)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address.PostalCode)
@Html.ValidationMessageFor(model => model.Address.PostalCode)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以提供任何建议,为什么我的返回ViewModel值在填充所有字段时为NULL?
我使用网络记录功能检查了谷歌浏览器浏览器,所有值都以JSON格式发回.
非常感谢.
------------编辑---------------
以下是我可以从Google Chrome网络监视器中看到的部分内容
公司名称:ABC123 Company.CreatedDate:2014/05/13 00:00:00 ....
所以肯定会被退回.
Mat*_*ion 11
我能够重现你的问题而感到困惑,因为我知道默认的MVC Model Binder理解复杂的类型.我剥离了大部分代码,只是试图用公司对象来做,但仍然失败了.然后我注意到在vmCompanyAddress中,类的名称也是属性的名称:
public class vmCompanyAddress
{
public StatelyTechAdmin.Models.Company Company { get; set; }
Run Code Online (Sandbox Code Playgroud)
我将属性的名称更改为与类名不同的名称,并开始工作:
public class vmCompanyAddress
{
public StatelyTechAdmin.Models.Company TheCompany { get; set; }
Run Code Online (Sandbox Code Playgroud)
Mar*_*sch 10
我们今天遇到了同样的问题.这个问题中接受的答案只是实际问题的一个肮脏的解决方法.
表单模型中的ClassName和PropertyName可以相同,模型绑定器中没有限制.限制是控制器中操作的参数.您不能将参数命名为表单模型中具有复杂类型的属性.导致绑定器尝试将HTTP POST表单值绑定company到控制器中的此参数.它不适合您,因为绑定器尝试将CompanyType 的值绑定 到CompanyAddresstype.
要解决您的问题,您只需将参数重命名company为companyAddressModel- 或任何不属于您的模型类中的属性.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CompanyAddress company)
Run Code Online (Sandbox Code Playgroud)
改成:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CompanyAddress companyAddressModel)
Run Code Online (Sandbox Code Playgroud)
有关模型绑定的更多信息,请参见此处:http://aspnetmvc.readthedocs.org/projects/mvc/en/latest/models/model-binding.html
MVC将尝试按名称将请求数据绑定到操作参数.MVC将使用参数名称及其公共可设置属性的名称查找每个参数的值.[...]除了路由值之外,MVC还将绑定来自请求各个部分的数据,并按设定顺序进行绑定.下面是模型绑定查看它们的顺序中的数据源列表:
- 表单值:这些是使用POST方法在HTTP请求中的表单值.
- 路由值:路由提供的路由值集.
- 查询字符串:URI的查询字符串部分.
ASP.NET WebAPI文档中的一个很好的例子,它使用相同的技术:
HttpResponseMessage Put(int id, Product item) { ... }
Run Code Online (Sandbox Code Playgroud)
这里的Id属性Product映射到id控制器中的参数.这将起作用,导致在操作中使用与模型类中相同的原始数据类型.
| 归档时间: |
|
| 查看次数: |
14097 次 |
| 最近记录: |