в asp.net-mvc, как лучше всего использовать Base ViewModel для отображения динамического содержимого на странице Site.Master - PullRequest
2 голосов
/ 07 ноября 2010

У меня есть сайт asp.net-mvc, и есть некоторая информация, которую я хочу показать на каждой странице.Я создал класс с именем BaseViewModel, и каждый из классов viewModel наследуется от BaseViewModel.Представление Site.Master привязывается к BaseViewModel напрямую.

В настоящее время базовый класс имеет одно свойство с именем MenuLinks.

Свойство menulinks заполняется из вызова базы данных, поэтому для каждого действия контроллера, которое являетсяСоздавая ViewModel, я добавляю новую строку:

 viewModel.MenuLinks = _repository.GetMenuLinks();

У меня много контроллеров, действий и моделей представлений.Есть ли какой-нибудь более чистый способ, которым я могу сделать выше, не помещая эту строку выше при каждом действии контроллера.

Ответы [ 5 ]

11 голосов
/ 07 ноября 2010

Вы можете написать собственный атрибут фильтра действий , который будет выполняться после каждого действия и устанавливать свойство базовой модели:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    base.OnActionExecuted(filterContext);
    var viewResult = filterContext.Result as ViewResultBase;
    if (viewResult != null) 
    {
        var model = viewResult.ViewData.Model as BaseViewModel;
        if (model != null)
        {
            model.MenuLinks = _repository.GetMenuLinks();
        }
    }
}

Теперь осталось только украсить базовый контроллер этим фильтром действий.

Другой способ справиться с этим - использовать дочерние действия и не иметь модели базового вида.

2 голосов
/ 11 июня 2011

Мне нравится пример Джастина, потому что он использует подход MVC. Я изменил его, чтобы он работал для MVC3 с бритвой. Вот что у меня есть в моем _Layout.cshtml:

        <div id="menucontainer">
            <ul id="menu">
                @Html.Action("Menu","Layout")
            </ul>
        </div>

Я создал LayoutController, у которого есть действие в меню:

public class LayoutController : Controller
{
    //
    // GET: /Layout/
    public PartialViewResult Menu()
    {
        var viewModel = new MenuViewModel {IsAdministrator = true};

        return PartialView(viewModel);
    }
}

, который отображает частичное имя представления Menu.cshtml

@model MenuViewModel
@if (Model.IsAdministrator)
{
   //render admin stuff
}
//render other items
2 голосов
/ 07 ноября 2010

на вашей странице site.master, звоните

<div id="menu-link">
  <% Html.RenderAction("Action", "Controller"); %>
</div>

Вы можете вызвать действие в вашем homecontroller, если хотите, и просто заставить его вернуть частичное представление html, в вашем случае некоторые ссылки в меню.

public class HomeController: Controller
{
    public ViewResult Menu() {
        var viewModel = new ViewModel();
        viewModel.MenuLinks = _repository.GetMenuLinks();

        return PartialView("MenuPartial", viewModel);
    }
}

вы можете создать частичный "MenuPartial.ascx"

<% foreach(var link in Model.MenuLinks) { %>
    <%: link.Name %>
<% }%> 
0 голосов
/ 08 ноября 2010

Создайте фабричный класс , который предоставит вам уже настроенную модель представления.

Class Factory{

  Repository _repository;

  public Factory(Repository repository){
    _repository = repository;
  }

  public ViewModel GetViewModel(){
    var viewModel = new ViewModel();
    viewModel.MenuLinks = _repository.GetMenuLinks();
    return viewModel;
  }

}

тогда в вашем контроллере вы можете использовать класс Factory вместо непосредственного создания экземпляра viewModel

   ... your controller ...
   var factory = new Factory(_repository);
   var viewMolde = factory.GetViewModel();
0 голосов
/ 07 ноября 2010

Я думаю, что лучший способ достичь вашего результата без изменения всех действий вашего контроллера - это создать фильтр пользовательских действий, который заполняет свойство вашей BaseModel ссылками в меню.

Тогда вы могли бы иметь класс BaseController и добавить атрибут в BaseController.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...