2010-01-22 3 views
4

Чем больше я использую ASP.NET MVC, тем больше мне это нравится. Однако в случае показа данных модели на главных страницах существует несколько способов сделать это. Я не уверен в лучшем решении.Данные главной страницы ASP.NET MVC

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

В веб-формах asp.net я обычно делаю это с помощью пользовательских элементов управления, каждый из которых выполняет свою собственную привязку данных для получения требуемых данных.

В MVC все данные должны передаваться контроллером.

Так, в отношении категорий самое простое решение, казалось бы передать это в виду данных в действии контроллера:

ViewData["Categories"] = _service.GetCategories(); 

Однако, делая это для каждого действия не очень DRY так следующий this article я создал базовый контроллер, который добавляет необходимые данные в моей ViewData:

public class AppController : Controller 
{ 
    IAppService _service; 

    public AppController() { } 
    public AppController(IAppService appService) 
    { 
     _service = appService; 
     SetSiteData(); 
    } 

    private void SetSiteData() 
    { 
     ViewData["Categories"] = _service.GetCategories(); 
    } 
} 

затем я создал расширение для ViewMasterPage:

 public static void RenderCategoryList(this ViewMasterPage pg) { 
     pg.Html.RenderPartial("CategoryList", pg.ViewData["Categories"]); 
    } 

И в моем MasterPage:

 <div> 
     <%this.RenderCategoryList(); %> 
    </div> 

Это кажется довольно чистый подход. Однако, это лучший способ, поскольку я также видел предложения по созданию ViewModel для вашего MasterPage. Я мог видеть, что, возможно, по мере роста ваших данных ViewModel это может быть лучшим решением.

Что касается статуса тележки, я полагаю, что я сделал бы что-то подобное, но не уверен, будет ли RenderAction более подходящим (When to use RenderAction vs RenderPartial with ASP.NET MVC). Спасибо, Бен

ответ

7

Это работает, хотя это не так, как я хотел бы сделать это по 2 причинам:

  1. Я не люблю вставлять данные в ViewState, так как вы, по сути брось как объект
  2. требуя базовый контроллер вы ограничивая функциональность контроллеров, которые наследуют от этого basecontroller (который не может быть проблемой, хотя)

Я думаю, что это было бы идеально использовать RenderAction (часть проекта MvcFutures). Этот помощник может использоваться для визуализации действия на другом контроллере. Таким образом, вы можете иметь ProductController с действием ListCategories, вы могли бы просто сделать что-то вроде:

<% Html.RenderAction<ProductController>(x => x.ListCategories()); %> 

ListCategories назвал бы

_service.GetCategories(); 

и можете прилипнуть информацию в свою собственную модель. Тогда это передаст, что модель для представления будет частичной страницей.

+1

+1 для RenderAction, это почти идеальное решение, после выхода MVC2 и вы можете кэшировать результаты RenderAction, это будет идеально. – mxmissile

+0

Нужно ли что-либо делать, чтобы использовать строго типизированный вызов RenderAction, который вы используете выше? Я использую предварительный просмотр mvc 2.0 и, похоже, не могу построить метод RenderAction таким образом. –

2

Спасибо - RenderAction была отличной работой.

Я получил дополнительную информацию от here.

Так что для блага других, вот пример того, как я выводя статус корзина

Действие:

[ChildActionOnly] 
    public ActionResult CartStatus() 
    { 
     return PartialView(_service.GetCartSummary()); 
    } 

Частичный вид (связан с Models.Cart)

<div class="cartSummary"> 
<%if (Model.HasItems) { %> 
    Cart Items: <%=Model.Items.Count() %> | Total: <%=Model.TotalItems %> 
<%} else {%> 
    Your cart is empty. Please buy stuff! 
<%} %> 

Вспомогательный метод для магистральной страницы:

public static void RenderCartStatus(this ViewMasterPage pg) { 
     pg.Html.RenderAction("CartStatus", "Catalog", null); 
    } 

И, наконец, мастер страницы:

<%this.RenderCartStatus(); %> 

Спасибо за совет.

+0

пытается реализовать эти решения, но я не могу понять, где создать вспомогательный метод для главной страницы? Создать какой-нибудь другой файл класса C#? – JBeckton

+0

@JBeckon - да, вы можете создать статический класс для размещения этих расширений. Просто не забудьте указать пространство имен в своем представлении или в web.config. –