2012-01-19 3 views
0

Я работаю с MVC3 и используя пользовательский ModelBinder, чтобы обойти ProducerListViewModel, который я создал.Как IMODELBinder поддерживает текущее состояние модели

Вот код контроллера Сейчас я работаю с:

Function Filter(user As UserModel, viewModel As ProducerListViewModel) As ActionResult 

     If IsNothing(viewModel) Then 
      viewModel = New ProducerListViewModel(user) 
     End If 

     Return View(viewModel) 

    End Function 

    <HttpPost()> _ 
    Function Filter(user As UserModel, viewModel As ProducerListViewModel, <Bind(Prefix:="Filter")> filterModel As ProducerFilterModel) As ActionResult 
     'update the filter in the view model and send off to the list method 
     viewModel.Filter = filterModel 
     Return RedirectToAction("List") 
    End Function 

    Function List(user As UserModel, viewModel As ProducerListViewModel) As ActionResult 

     Return Nothing 

    End Function 

Это код модели, который связан в обычае ModelBinder

<Serializable()> _ 
<ModelBinder(GetType(ProducerListViewBinder))> _ 
Public Class ProducerListViewModel 

    <XmlIgnore()> _ 
    Public Property Producers As IEnumerable(Of ProducerModel) 
    Public Property PagingInfo As New PagingInfoModel("Load More Producers") 
    Public Property Filter As New ProducerFilterModel() 

    Public Sub New(user As UserModel) 
     Me.Filter = ProducerFilterBL.Retrieve(user) 
    End Sub 

End Class 

Вот код для подшивки :

Public Class ProducerListViewBinder 
    Implements IModelBinder 

    Private Const __sessionKey As String = "ProducerListView" 

    Public Function BindModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext) As Object Implements IModelBinder.BindModel 

     Dim filter As ProducerListViewModel 

     'check to see if the filter exists in session 
     If IsNothing(controllerContext.HttpContext.Session(ProducerListViewBinder.__sessionKey)) Then 
      'load existing filter for user and store for later retrieval 
      Dim user As UserModel = UserBL.RetrieveUser() 
      filter = New ProducerListViewModel(user) 
      ProducerListViewBinder.SetItem(filter) 
     Else 
      filter = CType(controllerContext.HttpContext.Session(ProducerListViewBinder.__sessionKey), ProducerListViewModel) 
     End If 

     Return filter 

    End Function 

End Class 

поток выглядит следующим образом:

  1. Пользователь переходит фильтровать страницу, попав первое действие (Filter)
  2. Пользователь вносит изменения в фильтр и подает страницу, попав второе действие (Фильтр ж/сообщение)
  3. Фильтр ж/сообщение действие получает обновленный фильтр с использованием модели связывания (третий параметр filterModel As ProducerFilterModel), обновляет ProducerListFilterModel и перенаправляет к действию Список

Все работает просто отлично, но вот мой вопрос:

Почему в действии списка есть обновленная версия ProducerFilterModel внутри ProducerListViewModel?

Мне нравится, что он работает так прекрасно, я просто хочу знать, почему он работает.

+1

IModelBinder - это интерфейс. Простой договор. Он ничего не делает. Вы не указали нам код вашего связующего на заказ модели ProducerListViewBinder', и вы спросите нас, как это работает. Интересно, какой ответ вы ожидаете от такого вопроса. –

+0

@DarinDimitrov: Я добавил код для Binder.Причина, по которой я не думал добавлять код изначально, заключается в том, что когда я устанавливал точку останова в функции «BindModel», она не останавливалась там между вторым действием фильтра и действием «Список». Кстати, не нужно быть таким суровым. :) –

ответ

1

Теперь, когда вы показали код для вашего связующего, все очень ясно. Это связующее устройство хранит экземпляр ProducerListViewModel в сеансе, что позволяет ему пережить перенаправление.

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

Dim user As UserModel = UserBL.RetrieveUser() 
filter = New ProducerListViewModel(user) 
ProducerListViewBinder.SetItem(filter) 

и сохраняет это значение в сессия. Я думаю, что это ProducerListViewBinder.SetItem, который выполняет эту работу. К сожалению, вы не указали его код, но я готов сделать ставку 5 долларов, что это то, что он делает.

Затем выполняется действие Filter, а в конце оно перенаправляется на действие List, которое принимает аргумент ProducerListViewModel. Таким образом, ваше настраиваемое связующее устройство снова запускается, но на этот раз оно находит экземпляр, который он ранее хранил в сеансе, и он просто возвращает его оттуда.

Так что здесь нет никакой магии. Он просто использует сеанс ASP.NET, чтобы сохранить значения между переадресациями.

Смежные вопросы