There is an Index method, a NewsController controller. It shows a View with a collection of news.

Moreover, if it was a Request from the User’s account, then the news that this user created and no matter what his role is shown, it’s only important that this request was made from the User’s account. If Request is made from the Administrator's Cabinet, on the same Index method, then it shows the news of all users and renders the same View , but with enhanced functionality, and then the roles already come into play. If admin , then add. buttons.

Question: how best to do it?

I have several options, but I don’t know which one to choose:

  1. Based on 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" } ); 

Accordingly, already in the controller's method to check with which URL Request was made from, and building on this data, to tune the View functionality.

  1. Pass an additional parameter to the Index method of the News controller:

     public ActionResult Index(bool IsAdminCabinet, ... ) { ... } 
  2. Or add two more methods: News in the Profile and Admin controllers:

     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"); } } 
  • And why are you doing a redirect instead of simply selecting the news available to the user and displaying it? - PashaPash
  • and ktsta - TempData is actually a session. pure evil, will slow down and unscale - do not use it - stackoverflow.com/a/424111/177221 - PashaPash
  • The redirection is done, because in different parts of the application we need to get different data for one View, and, accordingly, render it with the data and functionality we need at the moment. About TempData did not know, thank you. - rpe4a
  • you can simply specify the name of the View when the ViewResult returns, and render the same view from two different actions. - PashaPash
  • Hmm, for sure, you can try. What about the fact that in the first case I need to render a View with admin functionality, and in the second I render a View with user functionality, but can it also be an admin? In one of the methods, you can use VIewBag.IsAdmin to try to configure the View? Did I understand you correctly? - rpe4a

2 answers 2

The result should not depend on the data that came from the client - otherwise an ordinary user will add ?IsAdminCabinet=true and there will be a scandal.

You know exactly the current user on the server. So, if we assume that the model has the same model, you have two options:

If the View is very similar - differ in the presence of buttons - use one 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); } } 

put one kind of News.cshtml in Shared, hide the buttons by @model.ShowAdminControls .

If the sample code (model building) is common for both users and administrators, then you can leave one controller and one action. Routes on it - at your discretion, they affect only the visible url in the address bar of the browser.

 public class NewsController : Controller { public ActionResult News() { var model = new NewsModel(); model.News = GetNewsVisibleForCurrentUser(); model.ShowAdminControls = CurrentUser.IsAdmin; return new View("News", model); } } 

If the types are really different, then

 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); } } 

Put two different views in the appropriate folders. Common html for news line render via RenderPartial .

  • Thanks, I will try! - rpe4a

For extended functionality, you can create different partial views.
In View, add a condition check and a call, for example, such

 @Html.Partial("~/Views/Shared/Admin.cshtml", model) 
  • There will be unnecessary duplication, support will become more complicated, I think. - rpe4a
  • you have a common to all roles should be in the View, and the specificity is made in separate partial'y. those. there will be no duplication. just in View there will be an if / switch which selects the desired partial. - Stack