Страницы

Поиск по вопросам

четверг, 11 июля 2019 г.

ASP.NET MVC 4. Как отобразить пользователям разную функциональность + в зависимости от requet'a на одной View?

Есть метод Index, контроллера NewsController. Он показывает View с коллекцией новостей.
Причем, если это был Request из кабинета Пользователя, то показываются новости, которые создал этот пользователь и не важно какая у него роль, важно только, что этот запрос был сделан из кабинета Пользователя. Если Request делается из кабинета Администратора, на этот же метод Index, то показывает новости всех пользователей и рендерит эту же View, но с расширенным функционалом, и тогда уже вступают в игру роли. Если Admin, то доп. кнопки.
Вопрос: как лучше это сделать?
У меня есть несколько вариантов, но какой выбрать я не знаю:
На основе Routes:
routes.MapRoute( name: "Admin News", url: "Admin/News", defaults: new { controller = "News", action = "Index" } );
routes.MapRoute( name: "Profile News", url: "Profile/News", defaults: new { controller = "News", action = "Index" } );
Соответственно уже в методе контроллера проверять с какого URL сделан был Request и отталкиваясь от этих данных заниматься настройкой функциональности View
Передавать дополнительный параметр в метод Index контроллера News
public ActionResult Index(bool IsAdminCabinet, ... ) { ... } Или же добавить еще два метода: News в контроллерах Profile и Admin
public class ProfileController : Controller { public ActionResult News() { return RedirectToAction("Index", "News"); } } public class AdminController : Controller { public ActionResult News() { TempData["IsAdminCabinet"] = true; return RedirectToAction("Index", "News"); } }


Ответ

Результат не должен зависеть от данных, пришедших от клиента - иначе обычный пользователь допишет ?IsAdminCabinet=true и будет скандал.
Вы же точно знаете текущего пользователя на сервере. Так, если предположить что модель у модель одинаковая, у вас два варианта:
Если View очень похожи - отличаются наличием кнопок - использовать один View:
public class ProfileController : Controller { public ActionResult News() { var model = new NewsModel(); model.News = GetRegularUserNews(); model.ShowAdminControls = false; return new View("News", model); } }
public class AdminController : Controller { [AdminOnly] public ActionResult News() { var model = new NewsModel(); model.News = GetAllNews(); model.ShowAdminControls = true; return new View("News", model); } }
положить один вид News.cshtml в Shared, спрятать кнопки по @model.ShowAdminControls
Если код выборки (построения модели) общий и для пользователей и для админов - то можно оставить один контроллер и одно действие. Роуты по нему - на ваше усмотрение, они влияют только на видимый url в адресной строке браузера.
public class NewsController : Controller { public ActionResult News() { var model = new NewsModel(); model.News = GetNewsVisibleForCurrentUser(); model.ShowAdminControls = CurrentUser.IsAdmin; return new View("News", model); } }

Если виды действительно разные - то
public class ProfileController : Controller { public ActionResult News() { var model = new NewsModel(); model.News = GetRegularUserNews(); return new View("News", model); } }
public class AdminController : Controller { [AdminOnly] public ActionResult News() { var model = new NewsModel(); model.News = GetAllNews(); return new View("News", model); } }
Положить два разных View в соответствующие папки. Общий html для строчки новостей рендерить через RenderPartial

Комментариев нет:

Отправить комментарий