我甚至不确定从哪里开始解释这个问题。我在过去的10个小时里一直在研究这个问题,而不知道根本原因是什么。如果需要任何其他细节,我很乐意提供。我只是在猜测这方面的相关内容。
我有一个MVC2站点,路由由Steve Hodgkiss设置的精彩RestfulRouting包,使用默认路由设置和嵌套控制器(例如/ customer / {custid} / location / {locid}等)
在这方面,我有一个特殊的模型给了我一些问题。出于某种原因,当创建页面将数据发送回我的服务器时,ModelBindingContext对象中的ModelName属性传递给DefaultModelBinder(我的自定义类继承自DefaultModelBinder,以处理从存储库中抓取对象)。这只发生在这一个模型上。我根本无法发现差异。
破碎的模型
public class RemedialItem : Entity
{
public virtual int Id { get; set; }
....
工作模式:
public class Customer : Entity
{
public virtual int Id { get; set; }
....
实体只是一个空类,用作反射使用的标记。
RemedialItemController.cs
[HttpGet]
public ActionResult New(int? locationId, int? applianceId)
{
var model = ViewModelFactory.Create<CreateRemedialItemViewModel>();
model.Categories = (from c in repository.Query<RemedialItemCategory>()
orderby c.Name
select c).ToList();
model.RemedialItem = new RemedialItem();
return View(model);
}
CustomerController.cs
[HttpGet]
public ActionResult New()
{
var viewModel = ViewModelFactory.Create<SingleCustomerViewModel>();
viewModel.Customer = new Customer();
return View(viewModel);
}
ViewModelFactory是一个注入类,用于处理设置所有视图模型共有的一些基本属性(主要是用户登录和用户详细信息)
破坏的视图模型:
public class CreateRemedialItemViewModel : ViewModelBase
{
public RemedialItem RemedialItem { get; set; }
public IList<Location> Locations { get; set; }
public IList<Appliance> Appliances { get; set; }
public IList<RemedialItemCategory> Categories { get; set; }
}
正在运行的ViewModel:
public class SingleCustomerViewModel : ViewModelBase
{
public Customer Customer { get; set; }
}
ViewModelBase包含一些由ViewModelFactory填充的属性。
在RemedialItem的新视图中损坏的表单:
<% using(Html.BeginForm("Create","RemedialItem",FormMethod.Post))
{%>
<%: Html.AntiForgeryToken() %>
<fieldset>
<legend>General</legend>
<div>
<%: Html.LabelFor(m=>m.RemedialItem.Category) %>
<%:Html.DropDownListFor(m=>m.RemedialItem.Category.Id, new SelectList(Model.Categories,"Id","Name")) %>
</div>
<div>
<%: Html.LabelFor(m=>m.RemedialItem.Item) %>
<%: Html.TextAreaFor(m=>m.RemedialItem.Item) %>
</div>
<div>
<%: Html.LabelFor(m=>m.RemedialItem.Note) %>
<%: Html.TextAreaFor(m=>m.RemedialItem.Note) %>
</div>
<input type="submit" value="Create Item" />
</fieldset>
<%}%>
一个有效的新观点:
<% using (Html.BeginForm("Create","Customer",FormMethod.Post)) {%>
<%: Html.ValidationSummary(true) %>
<%:Html.AntiForgeryToken() %>
<fieldset>
<legend>Fields</legend>
<p>
<%: Html.LabelFor(m=>m.Customer.Name) %>
<%: Html.TextBoxFor(m=>m.Customer.Name) %>
</p>
<p>
<%: Html.LabelFor(m=>m.Customer.Street) %>
<%: Html.TextBoxFor(m=>m.Customer.Street) %>
</p>
[...tl;dr...]
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
两者都产生类似的字段名称:
断裂:
<label for="RemedialItem_Item">Item</label>
<textarea cols="20" id="RemedialItem_Item" name="RemedialItem.Item" rows="2">
</textarea>
工作:
<label for="Customer_Name">Name</label>
<input id="Customer_Name" name="Customer.Name" type="text" value="" />
我为过长的代码转储道歉,简而言之:
当回发到创建表单上时,工作集的内容将ModelName设置为Customer
。破碎的东西是一个空字符串
有什么我想念的吗?有没有人遇到过这样的事情?
答案 0 :(得分:0)
我发现了这个问题。在ViewModel中,显示RemedialItem
实例的属性称为RemedialItem
。在它发布的操作中,带有RemedialItem
实例的参数被称为item
,这破坏了所有内容。
简而言之,在使用ViewModel时,请确保从ViewModel获取对象的参数名称与viewmodel中的属性名称相同。
我的日子过去了。