#c# #asp.net-mvc-3 #model-view-controller #coding-style
#c# #asp.net-mvc-3 #модель-представление-контроллер #стиль кодирования
Вопрос:
После того, как я нашел это в нашем коде, я понял несколько вещей:
- «сделай это сейчас, исправь позже» имеет ограничение
- На самом деле я не знаю, куда это идет с MVC3
@model int @using Company.Core.Logic.Financial @using Company.Core.Repositories @{ var values = from AccountPlan e in new AccountPlanRepository().GetItemList() where String.IsNullOrEmpty(e.PromoCode) // filter out promotional plans select new { id = e.AccountPlanId, name = e.Description }; var items = new SelectList(values, "id", "name", Model); } @Html.DropDownListFor(m => m, items)
В частности, это шаблон редактора ( @Html.EditorFor(m => m.AccountPlan)
), но это заставило меня понять, что я не знаю, где этот код используется для обычных вещей, таких как конструкторы меню. Если вы используете макеты для MVC3 (а кто нет), где код для построения меню сверху на основе ролей пользователя? Я бы предположил, что код представления будет перебирать готовые пункты меню и изменять их в HTML, но поскольку модель строго типизирована, означает ли это, что все модели должны знать о пунктах меню?
На этот раз именно здесь веб-формы имели для меня больше смысла, поскольку это было бы в коде, но я действительно хочу уйти от этого.
редактировать: несмотря на то, что я начал спрашивать о коде макета, я предполагаю, что он также работает для EditorTemplates и DisplayTemplates. Если это неверное предположение, пожалуйста, дайте мне знать, куда они должны идти.
редактирование 2: В конечном итоге я хочу иметь чистое, возможно, даже зависимостно-инъекционное место для запуска кода, который вызывается из EditorTemplate
. Возможно, это тот случай, когда EditorTemplate немедленно вызывает RenderAction?
Ответ №1:
Похоже, это довольно хорошо решает проблему (см. Отмеченный ответ, а не исходный вопрос):
В принципе, вызовите RenderAction(...)
, и он построит нужную модель, а не заставит вас требовать, чтобы для каждой модели требовался список пунктов меню.
Комментарии:
1. это кажется разумной идеей.
2.
RenderAction
решит мою проблему, если я смогу заставить шаблоны редактора вести себя так же.
Ответ №2:
Лично для меня я часто фильтрую меню на основе групп Active Directory, поэтому мне нужно знать, каковы их уровни доступа во всем приложении.
Я создаю новый контроллер, который я называю ControllerBase
public class ControllerBase : Controller
{
//authorization group setting an menu creation here.
//set properties and objects to ViewBag items to access from the front end.
protected override void Dispose(bool disposing)
{
_db.Dispose();
base.Dispose(disposing);
}
}
а затем на всех других контроллерах в моем проекте я просто расширяю из ControllerBase
public class HomeController : ControllerBase
{}
Это сохраняет всю логику моего сервера в одном файле для управления разрешениями и предоставляет всем моим страницам доступ к этим переменным, когда мне нужно скрыть или показать разные элементы пользовательского интерфейса на основе разрешений.
Ответ №3:
Дочерние действия идеально подходят для этого сценария. Логика, необходимая для создания представления, заключена в действие контроллера, как обычно, и представление, которое хочет использовать дочернее действие, просто отображает действие..
Вы также можете кэшировать эти частичные представления, что имело бы смысл для чего-то вроде главного меню — поскольку, предположительно, разрешения пользователей не будут меняться так часто.
например
[OutputCache(Duration = 300)]
[ChildActionOnly]
public ViewResult MainMenu()
{
var model = GetMenuModel();
return View(model);
}
Представление, которое хочет отобразить дочернее действие, делает это следующим образом.
@{ Html.RenderAction("MainMenu", "Account"); }
И, таким образом, представлению, вызывающему дочернее действие, не нужно знать, какая модель требуется для представления.
Существуют также перегрузки при визуализации, если ваше дочернее действие потребует от вас передачи ему параметров.
Комментарии:
1. По сути, так я обрабатываю свое главное меню и несколько других блоков HTML-кода типа «виджет», отображаемых в разных представлениях. Этот шаблон работает хорошо.
Ответ №4:
Вы не должны (должны) обращаться к репозиторию внутри представления. Это относится к контроллеру.
И меню реализовано на главной странице, вы не даете много подробностей о специфике.
Комментарии:
1. я не думаю, что это действительно отвечает на вопрос. он запрашивает рекомендации о том, как получать и передавать глобальные данные в _layout или какой-либо другой объект, не относящийся к представлению.
2. (Начало) вопроса не соответствует названию. Существует некоторый код Linq для заполнения выпадающего списка вопросом «куда это ведет».
3. Не уверен, почему вы проголосовали против, так что ставьте 1. Я хорошо знаю, что я (ну, я этого не писал …) не должен обращаться к репозиториям или, если на то пошло, создавать что-либо в представлении. Я обновлю свой вопрос, чтобы сделать это немного более очевидным.