Asp.net MVC2 ModelBindingContext.ModelName пусто - PullRequest
0 голосов
/ 14 сентября 2010

Я даже не совсем уверен, с чего начать объяснение этой проблемы. Я работал над этим в течение прошлых 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. Разбитый материал - пустая строка

Есть что-то, что я пропускаю? Кто-нибудь сталкивался с чем-то подобным раньше?

1 Ответ

0 голосов
/ 14 сентября 2010

Я нашел проблему.В ViewModel свойство, которое содержало экземпляр RemedialItem для отображения, называлось RemedialItem.В действии, которое он опубликовал, параметр, который принял экземпляр RemedialItem, назывался item, и это сломало все.ViewModel совпадает с именем свойства в viewmodel.

Вот и прошел мой день.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...