MVC3 RenderPartial и ViewBag
Я постараюсь сохранить это вкратце:
В представлении
@Html.RenderPartial("myview", Model.SubModel,
new ViewDataDictionary()
{
{ "thing", Model.Thing }
})
В myview мы видим, что "вещь" доступна, то есть это дает значение Model.Thing в представлении myview:
@ViewBag.thing
Большой! просто
Но мне нужно что-то делать с вещью (и, кстати, вещь не может быть частью SubModel), т.е. получить доступ к этому в моем механизме просмотра или в идеале в контроллере, например:
public ActionResult myview(SubModelType vm)
{
var thing = ViewBag.thing; // oh dear this doesnt exist.. but is there when the view is rendered
Поэтому мой вопрос: если ViewBag доступен в полученном myview, он должен быть каким-то образом передан в httpcontext или в controlcontext где-нибудь, верно? Кто-нибудь знает, почему он не доступен в контроллере, но в поле зрения и как я мог бы получить доступ к этому?
редактировать
Извините, я упустил важный момент здесь! Это когда myview отправляется обратно в контроллер, вызывая действие myview, где я ожидаю, что ViewBag, отображаемый для myview, будет доступен. Но, конечно, это не так, он был использован в "myview" и все. Поэтому, если я хочу использовать его в действии myview, мне нужно будет сохранить его в ViewBag в этом представлении ИЛИ установить некоторое значение модели представления, чтобы оно могло быть возвращено действию.
Имеет ли это смысл?
1 ответ
Извините, я упустил важный момент здесь! Это когда myview отправляется обратно в контроллер, вызывая действие myview, где я ожидаю, что ViewBag, отображаемый для myview, будет доступен.
О нет, вы не можете ожидать ничего подобного. Это не так, как работает ASP.NET MVC. Когда вы отправляете HTTP-запрос к действию контроллера, механизм связывания моделей по умолчанию перехватывает этот запрос, просматривает опубликованные значения из запроса и связывает их с аргументом действия:
[HttpPost]
public ActionResult myview(SubModelType vm, ThingViewModel thing)
{
...
}
Это, очевидно, предполагает, что значения этих вещей были частью исходного запроса. Так, например, если вы отправляете форму, вы должны включить в эту форму соответствующие поля, которые может использовать связыватель модели.
Подумайте об этом так: действие контроллера ASP.NET MVC может быть вызвано из любого клиента. Например, из приложения для iPhone. И, как вы знаете, нет такого понятия, как ViewBag
в iOS Все, что произойдет, - это то, что механизм связывания моделей по умолчанию будет смотреть на значения POST и пытается гидрировать модели представлений, которые ваши действия принимают в качестве аргументов.
Если, с другой стороны, вы не можете задавать значения этих вещей как часть запроса (путем включения соответствующих полей ввода в форму), вы можете только отправить идентификатор этого тонкого элемента из скрытого поля, а затем внутри действия контроллера использовать этот идентификатор для запроса ваше базовое хранилище данных для извлечения вещи из того же места, где вы извлекли ее изначально, когда впервые отображали эту форму.
Некоторые люди могут также предложить вам сохранить Вещи внутри Сессии, а затем прочитать значение обратно из Сессии в вашем действии POST. Я не из тех людей. Это альтернативный подход, хотя.