In MVC 5 I am attempting to use the controller to render a partial view only if the (Windows Authenticated) user belongs to one or more of a list of Active Directory groups. There are over 30 distinct groups I need to account for, so the "hello world" examples don't fit my needs. After playing scavenger hunt on the web, I managed to collect this much. No compile or runtime errors, but the content is showing for all users rather than the specific users. So the desired outcome is not yet achieved.
While I can achieve the desired outcome using if-then logic in the view, it creates a lot of unnecessary duplication and encourages spaghettification. So I'm trying to do this in the controller.
Summary of Desired Outcome:
When the user loads the viewpage, the partial view should only render if the Windows Authenticated user belongs to one or more of a list of groups defined in the controller action. If the user is not authorized, then the partial view is not included.
Controller Block:
[ChildActionOnly]
[Authorize(Roles="Domain\\GroupA,Domain\\GroupB")]
public ActionResult MonitorCSU()
{
return PartialView("MonitorCSU");
}
View Block:
<div class="rowWithCols3">
@Html.Partial("MonitorCSU")
Unsuccessful Iterations:
In the controller block I tried (unsuccessfully) to use an if-then block, the else case being another partial view with no content.
[ChildActionOnly]
public ActionResult MonitorCSU() { if (User.IsInRole("Domain\GroupA")) { return PartialView("_MonitorCSU"); } else { return PartialView("_Unauthorized"); } }In Razor, I tried using HTML.Action but when I tried run the page the browser hung in an infinite loop.
Thanks to @Stephen Muecke and and a commenter whose entry has mysteriously vanished, I have the missing pieces.
I was able to test this code with several real users and verified the desired behavior happens consistently.
Controller Block: Main difference: take out authorization and use an if-then block send one of two partial views.
View Block: The key difference is using HTML.Action
@Html.Partial()
returns a partial view without calling a controller method. In order to call your controller method, you need to useor
Note this assumes that the
MonitorCSU()
method is in the same controller as the method that generates the main view (other wise you also need to include a parameter for the controller name)Refer documentation
While you've found a solution, you're going to have other problems with it. I would suggest a different approach, which is to use EditorTemplates and create a separate model for the html you want to render. Then, at runtime you would check whether the user is in the groups you specify, and if they are, you create an instance of the model, and if they are not you leave the model null. In this way, when the view is rendered with EditorFor(), it will ignore and not render the template for users who do not have access.