Сложная ViewModel ASP.MVC 1.0 не заполняется на Action - PullRequest
2 голосов
/ 06 февраля 2010

Я за 3 дня изучаю MVC для нового проекта, и мне удалось натолкнуться на множество проблем, с которыми я столкнулся, - в основном о чем-то столь же простом, как перемещение данных в представление и обратно в Контроллер типобезопасным (и управляемым) способом. Это самое последнее.

Я видел это ранее, но ничего не советовало, похоже, сработало. У меня сложный вид модели:

public class IndexViewModel : ApplicationViewModel
{
 public SearchFragment Search { get; private set; }

 public IndexViewModel()
 {
  this.Search = new SearchFragment();
 }
}
public class SearchFragment
{
 public string ItemId { get; set; }
 public string Identifier { get; set; }
}

Это соответствует (главная страница указателя):

%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IndexViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <% Html.BeginForm("Search", AvailableControllers.Search, FormMethod.Post); %>
    <div id="search">
        <% Html.RenderPartial("SearchControl", Model.Search); %>
    </div>
    <% Html.EndForm(); %>
</asp:Content>

и UserControl:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SearchFragment>" %>

<p>
    <label for="itemId">
        <%= Html.Resource("ItemId") %></label>
    <%= Html.TextBox("itemId", Model.ItemId)%>
</p>
<p>
    <label for="title">
        <%= Html.Resource("Title") %></label>
    <%= Html.TextBox("identifier", Model.Identifier)%>
</p>
<p>
    <input type="submit" value="<%= Html.Resource("Search") %>" name="search" />
</p>

Возвращается к следующему методу:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(IndexViewModel viewModel)
{
 ....
}

Моя проблема заключается в том, что когда модель представления повторно гидратируется из представления в ViewModel, элементы SearchFragment становятся пустыми. Я подозреваю, что это связано с тем, что механизм связывания модели по умолчанию не реализует элементы HTML ItemId и Identifier, визуализированные как встроенные на карте View в классе SearchFragment. Когда у меня есть два дополнительных свойства (ItemId и Identifier) ​​в IndexViewModel, значения связаны правильно.

К сожалению, насколько я могу судить, я должен использовать SearchFragment, так как он мне нужен для строгого ввода Search UserControl ... поскольку элемент управления можно использовать везде, где он может работать в любом родительском представлении.

Я действительно не хочу, чтобы он использовал "волшебные струны". Слишком много всего происходит уже в ИМО.

Я пытался добавить префикс HTML к «Поиску». в надежде, что связыватель модели распознает «Search.ItemId» и будет соответствовать свойству IndexViewModel «Search» и ItemId внутри него, но это не работает.

Боюсь, мне придется написать свой собственный ModelBinder, чтобы сделать это, но, конечно, это должно быть то, что вы можете сделать из коробки ??

В противном случае, есть ли другие предложения (или ссылка на кого-то, кто уже сделал это?)

Вот надеемся ....


Спасибо, пока. Совершенно очевидно, что это довольно основное требование отсутствует в MVC: p

Ответы [ 3 ]

1 голос
/ 06 февраля 2010

Я думаю, что ваша проблема может быть здесь:

public IndexViewModel()
{
  this.Search = new SearchFragment();
}

Вы пытались оставить свойство поиска пустым?Я знаю, что защищенный метод CreateModel в DefaultModelBinder не сработает, если значение уже нулевое, но я не уверен насчет установки свойств.Дайте ему шанс, если вы еще этого не пробовали ...

РЕДАКТИРОВАТЬ:

Я только что заметил:

<%= Html.TextBox("identifier", Model.Identifier)%

Должно быть:

<%= Html.TextBox("Search.Identifier", Model.Identifier)%
0 голосов
/ 08 февраля 2010

Первые мысли о том, что свойства SearchFragment не совпадают с регистром полей формы.

Я могу ошибаться, но, возможно, стоит проверить.

Редактировать

При дальнейшем изучении вы также можете учитывать тот факт, что форма использует SearchFragment, а View использует IndexViewModel - почему бы просто не использовать SearchFragment в качестве ViewModel?

0 голосов
/ 08 февраля 2010

Возможно, вам следует попробовать изменить метод действия на что-то вроде этого и выполнить привязки вручную:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(FormCollection formCollection)
{
   var viewModel = new IndexViewModel();
   viewModel.Search.ItemId = formCollection[0];
   viewModel.Search.Identifier = formCollection[1];
   ...
}

Но этот подход чем-то похож на создание собственного связующего.

...