Вот сценарий. Допустим, у меня есть сайт с двумя контроллерами, отвечающими за отображение разного типа контента - страниц и статей. Мне нужно встроить частичное представление на мою главную страницу, которая будет отображать страницы и статьи, отфильтрованные по некоторым критериям, и отображаться на каждой странице. Я не могу установить модель на своей главной странице (я прав?). Как решить эту задачу с помощью Html.RenderPartial?
[РЕДАКТИРОВАТЬ] Да, я бы, вероятно, создал отдельные частичные представления для перечисления статей и страниц, но все же есть барьер, который я не могу и не должен устанавливать на главной странице. Мне нужно как-то сказать «вот страницы» в качестве аргумента для моей части рендеринга, а также для статей. Вся концепция renderpartial с данными из базы данных на мастер-страницах для меня немного размыта.





Свойство ViewData Model следует использовать только для контента, который вы просматриваете / редактируете в основном разделе пользовательского интерфейса.
Другим частям представления могут потребоваться некоторые данные, присутствующие в ViewData, поэтому просто добавьте их в словарь.
Я бы просто передал данные из словаря следующим образом: ViewData ["статьи"] в партиал. (или ViewData.Get () из MvcContrib).
Вы также можете взглянуть на недавно реализованный шаблон субконтроллера, реализованный в MvcContrib.
да, это правильно. но давайте посмотрим на этот сценарий: для представлений, связанных со статьями, у меня будет ViewData ["article"], а для представлений, связанных со страницами, у меня есть ViewData ["pages"], но у меня нет и статей, и страниц, доступных постоянно. Итак, если я добавлю:
Html.RenderPartial ("статьи", ViewData ["статьи"])
Html.RenderPartial ("pagesView", ViewData ["страницы"])
на мою главную страницу, я буду генерировать исключение на каждой странице, на которой ViewDataDictionary не содержит как статей, так и страниц.
По крайней мере, я так это вижу.
У меня был похожий пост, и я придумал объектную модель для его обработки.
Я НЕНАВИЖУ не строго типизированные представления, поэтому пошел с этим подходом, и он хорошо работает.
Как насчет создания метода расширения HtmlHelper, который позволяет вызывать результат частичного просмотра для действия на контроллере.
Что-то вроде
public static void RenderPartialAction<TController>(this HtmlHelper helper, Func<TController, PartialViewResult> actionToRender)
where TController : Controller, new()
{
var arg = new TController {ControllerContext = helper.ViewContext.Controller.ControllerContext};
actionToRender(arg).ExecuteResult(arg.ControllerContext);
}
затем вы можете использовать это на своей главной странице, например
<% Html.RenderPartialAction((HomeController x) => x.RenderPartial()) %>
и в вашем контроллере соответствующий метод
public PartialViewResult RenderPartial()
{
return PartialView("~/Path/or/View",_homeService.GetModel())
}
В любом случае, это мои 2 цента
Я справляюсь с этим с помощью BaseViewModel. Все представления строго типизированы для модели представления, наследуемой от BaseViewModel.
Класс BaseViewModel содержит всю информацию, необходимую для MasterPage. Итак, для навигации ваша BaseViewModel может выглядеть так:
public class BaseViewModel
{
public BaseViewModel()
{
NavigationItems = RetrieveNavigationItemsFromModel();
}
public List<NavItems> NavigationItems {get; set;}
}
В MasterPage и PartialViews вы можете привести модель к BaseViewModel и получить доступ к свойству NavigationsItems.
<ul>
<% foreach (NavItem ni in (Model as BaseViewModel).NavigationItems) { %>
<li>
<a href = "<%= ni.Url %>" alt = "<%= ni.Alt%>"><%= ni.DisplayText %></a>
</li>
<% } %>
</ul>
Я думаю, что ваше решение может лежать в основе MVC 2.0 RC и не только ...
Фил Хаак разместил в своем блоге статью: http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx
Это очень поздний ответ, но я попал на эту страницу во время поиска в Google - так что есть вероятность, что кто-то еще увидит этот вопрос (и мой ответ).
Я решил эту проблему с помощью простого сценария jQuery для загрузки PartialView и выполнения его кода контроллера. Образец ниже.
<asp:Content ID = "indexContent" ContentPlaceHolderID = "MainContent" runat = "server">
<script type = "text/javascript">
$(document).ready(function() {
$("#applicationForm").load("/Home/ApplicationForm");
});
</script>
<div id = "applicationForm" />
</asp:Content>
Большим недостатком этого подхода является то, что для работы клиента необходимо включить скрипты (так что это действительно недружелюбно для SEO). Если это то, с чем можно жить, это хорошо работает. Я использую его только на сайте интрасети, где я знаю, что у каждого клиента включен JavaScript, и мне не нужно беспокоиться о ботах Google.