2015-03-19 6 views
1

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

Я хочу использовать частичный вид для этого. В настоящее время в ~/Views/Categories Я создал частичный вид _CategoriesHeader.cshtml. (Я сделал это, выбрав "Partial View" в диалоговом окне "Create New View", так что это на самом деле частичный вид)

содержимое _CategoriesHeader.cshtml являются следующие:

@model IEnumerable<Webshop.Models.Category> 

@{ 
    Layout = null; 
} 

<ul> 
    @foreach (var category in Model) 
    { 
     <li>@Html.ActionLink(category.Name, "Category", "Categories", new { ID = category.CategoryID }, null)</li> 

    } 
</ul> 

Сейчас в ~/Views/Shared/_Layout.cshtml я добавил следующий фрагмент кода:

@Html.Partial("~/Views/Categories/_CategoriesHeader.cshtml", new Webshop.DAL.ShopContext().Categories.ToList()) 

Мне интересно, если это правильный способ использования частичных представлений, требующих модели. Теперь он только встроенный создает новый объект DbContext для получения всех категорий, но я думаю, что лучше иметь модель. Но я не знаю, как это сделать. Я сделал что-то, где у CategoriesController.cs был метод для этого частичного представления, но это не сработало, потому что в содержащем представлении уже была загружена собственная модель.

+3

Воспроизведение 'DbContext' в представлении противоречит шаблону MVC. Вы должны изменить модель основного представления как объекта, который содержит все элементы для представления и любые частичные. – Nate

+0

Есть ли какая-либо конкретная причина, по которой вы хотите перечислить категории продуктов в виде частичного представления? – RavB

+0

Потому что я хочу, чтобы это было на каждой странице этого веб-клиента. Есть ли способ лучше? – JeroenJK

ответ

1

Что вы может сделать, это использовать Html.Action или Html.RenderAction. Это позволит избежать вызова любого DAL из представления. У контроллера больше всего есть действие, аннотированное как ChildActionOnly, и внутри действия, как и выше, ответьте на комментарий, используйте Return PartialView.

+0

Я попытался использовать этот метод. В _Layout.cshtml у меня есть '@ Html.Action (" КатегорииHeader "," КатегорииController ")'. В CategoriesController.cs у меня есть метод CategoriesHeader (аннотируется с ChildActionOnly), который возвращает PartialView (с _CategoriesHeader.cshtml и моделью). Но теперь я получаю 'Контроллер для пути '/' не был найден или не реализует IController.'. Я понятия не имею, почему и попробовал некоторые решения, которые не сработали. – JeroenJK

+0

Хм. Я использовал «КатегорииController» как имя контроллера для '@ Html.Action()', который должен быть «Категории» (поскольку компилятор знает, что это контроллер). Это решение вышеупомянутой ошибки. – JeroenJK

+0

Просто из любопытства я снова возился с PartialViews (создавая корзину для покупок, которую нужно перезагрузить при добавлении продукта, который не работал с ChildActionOnly). Но теперь я удалил ChildActionOnly, и сайт все еще работает. Является ли ChildActionOnly просто для того, чтобы не допустить его как полную страницу или что-нибудь еще? – JeroenJK

4

Нет. Вы не должны делать никаких действий DAL внутри представления. Я бы рекомендовал использовать только if, foreach и аналогичные заявления. Ничего больше. Подготовьте свои данные в своем контроллере и передайте его.

Вы должны положить new Webshop.DAL.ShopContext().Categories.ToList() в свою модель, которая используется в главном окне, и передать это частичному виду.

@Html.Partial("~/Views/Categories/_CategoriesHeader.cshtml", Model.Categories) 

Вам может понадобиться foreach, если вы хотите, чтобы отобразить данные в виде списка.

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

@Html.Action("CategoriesHeader") 
+1

Я думаю, что его проблема в том, что частичная часть находится на странице макета. Чтобы использовать вашу технику, он должен будет иметь категории для каждой модели для каждой страницы (возможно, наследуется от базового класса). Если я не прочитаю это неправильно. – RickJames

+0

Да. Дело в том, что я хочу отображать этот список категорий на КАЖДОЙ странице, поэтому я поместил его в _Layout.cshtml. И у всех этих страниц уже есть своя модель ... Поэтому я понятия не имею, как мне это сделать. – JeroenJK

+0

Просто выведите базовый класс и установите его там. –

0

Другой подход - вернуть частичный вид с вашего контроллера. Действие вашего контроллера будет отвечать за загрузку модели в частичное представление. Код вашего контроллера будет выглядеть примерно так:

public PartialViewResult GetYourPartialView(string id) 
     { 
      var vm = new yourviewmodel();   
      return PartialView("_YourPartialView", vm); 
     } 

Теперь у вас загруженный частичный вид.

2

Использование дочерних действий.

ShopController.cs

[ChildActionOnly] 
public ActionResult CategoryList() 
{ 
    var categories = new Webshop.DAL.ShopContext().Categories.ToList(); 
    return PartialView("_CategoryList", categories); 
} 

_CategoryList.cshtml

@model IEnumerable<Webshop.Models.Category> 

<ul> 
    @foreach (var category in Model) 
    { 
     <li>@Html.ActionLink(category.Name, "Category", "Categories", new { ID = category.CategoryID }, null)</li> 

    } 
</ul> 

_Layout.cshtml

@Html.Action("CategoryList", "Shop") 
+0

Это практически то, что я сделал сейчас, но поскольку это то же самое решение, что и @LeonardoNeninger, я прокомментировал здесь новое сообщение об ошибке. – JeroenJK

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