Я даже не совсем уверен, с чего начать объяснение этой проблемы. Я работал над этим в течение прошлых 10 часов без понятия о том, какова основная причина. Если понадобятся какие-либо дополнительные детали, я буду рад предоставить. Я просто догадываюсь, что актуально на данный момент.
У меня есть сайт MVC2 с маршрутами, созданными замечательным пакетом RestfulRouting Стива Ходжкисса, использующим настройку маршрута по умолчанию с вложенными контроллерами (например, / customer / {custid} / location / {locid} и например).
В этом у меня есть одна конкретная модель, которая вызывает у меня проблемы. По какой-то причине, когда страница создания страницы отправляет данные обратно на мой сервер, свойство ModelName в объекте ModelBindingContext передается в 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
. Разбитый материал - пустая строка
Есть что-то, что я пропускаю? Кто-нибудь сталкивался с чем-то подобным раньше?