Multiple layouts in ASP.NET MVC Core - asp.net

In our ASP.NET Core application we have several roles, we want each role has its own layout, for doing this we came up with idea of having separate layout for each role:
~/Views/Shared/Layouts/_DefaultLayout.cshtml
~/Views/Shared/Layouts/_Role_1_Layout.cshtml
~/Views/Shared/Layouts/_Role_2_Layout.cshtml
~/Views/Shared/Layouts/_Role_3_Layout.cshtml
~/Views/Shared/Layouts/_Role_4_Layout.cshtml
For switching between these roles we modify the ~/Views/_ViewStart.cshtml to this:
#{
if (this.User.IsInRole("Role1"))
{
Layout = "~/Views/Shared/Layouts/_Role_1_Layout.cshtml";
}
else if (this.User.IsInRole("Role2"))
{
Layout = "~/Views/Shared/Layouts/_Role_2_Layout.cshtml";
}
// ....
else
{
Layout = "~/Views/Shared/_DefaultLayout.cshtml";
}
}
this works in the first place, but when I log in with another user with for example Role1, instead of switching the current layout to use _Role_1_Layout.cshtml, it displays a blank page.
Any idea?

Looks like you fitting 'else', but there is a mistake in the path?
Layout = "~/Views/Shared/_DefaultLayout.cshtml";
Probably, should be:
Layout = "~/Views/Shared/Layouts/_DefaultLayout.cshtml";
I this is not a cause of your problem, could you share repo with your code or at least working example??

Simply set Layout to the name of the layout not to the path of the layout:
if (this.User.IsInRole("Role1"))
{
Layout = "_Role_1_Layout";
}
....

Related

how to remove _layout for admin dashboard

I want to exclude _layout for specific admin dashboard View. The only way I'm aware is with JS to hide those divs. Is there any other way?
In the razor page for which you don't want to use a layout, you can do:
#{
Layout = null;
}
If you want to exclude Layout from view temporarily, you can return view from a controller action using this code
if(...) return PartialView("name",model);
return View("name",model)
When you return a partial view, it will show only a view, no a layout
If your wont to exclude a layout permanenly for some views, you can use this code inside of the view
#{
Layout = null;
}
but don't forget that a Layout usually contains the most of Javascript and css libraries. So it is better to create a special layout for some views.
or you can use ViewStart page
#{
string CurrentName = Convert.ToString(HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"]);
dynamic Layout;
switch (CurrentName)
{
case "User":
Layout = "~/Views/Shared/_Layout.cshtml";
break;
default:
//Admin layout
Layout = "~/Views/Shared/_AdminLayoutPage.cshtml";
break;
}
}

ASP.NET Using DB-Context in _layout.cshtml

I'm trying to access the database context from _layout.cshtml to select notifications and display them in a dropdown box.
Can anyone tell me how to get the context in layout? I'm using razor-pages.
Look into ViewComponents. They are perfect candiates for this task. You can hookup to a db and return the data to your dropdown component then you can add them to your layout page like this.
#await Component.InvokeAsync("NotificationList", new { maxPriority = 2, isDone = true })
or like a tag helper
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-2.1

Role specific controls in Views

I'm trying to hide controls based on a user's role. I used to be able to do something like
#if (User.IsInRole("Admin"))
{Html.ActionLink("RolesAdmin", "Index", "RolesAdmin")}
in the view but this doesn't seem to work anymore. After much digging I found that Identity 2.0 doesn't use this at all.
Is there still something I can use directly from the View? Or am I doing this completely wrong?
This should still work fine, as the identity samples are currently doing something similar to only display top level links for "Admins"
#if (Request.IsAuthenticated && User.IsInRole("Admin")) {
<li>#Html.ActionLink("RolesAdmin", "Index", "RolesAdmin")</li>
<li>#Html.ActionLink("UsersAdmin", "Index", "UsersAdmin")</li>
}
This type of logic is better placed inside a controller, leave the views for rendering.
You can use Html.Action with a combination of ChildActions in your controller and render partial views depending on the users role.
I posted a question similar to this a while ago and think it would be helpful to you.
Role Based Navigation
-EDIT-
For clarification, this works using the new ASP.NET Identity
This would go in the layout
#Html.Action("BuildNavigation", "Component")
And this would be your controller.
public class ComponentController : Controller
{
[ChildActionOnly]
public ActionResult BuildNavigation()
{
if (this.User.IsInRole("customer"))
{
return PartialView("_NavigationCustomer");
}
else
{
return PartialView("_NavigationBasic");
}
}
}
This should get you going in the right direction.

tree navigation to show folder structure

Project: ASP.NET 3.5 with C#
I have this much :-
A table which used to store the "Folders". Each folder may contain sub folders and files. So if I click a folder, I have to list the content of the folder.
So I want to tell the user where he is now some thing like the following
Parent Folder --> Child Folder1 --> Child Folder1_1
Which ASP.NET control should I use here? How can I accomplish this task?
I think SiteMapPath is the best option. What you think ?
I hope the folder structure might be a dynamic one, so using SiteMap control is some what difficult. I will recommend you to manually do this my maintaining a ViewState/SessionState stored variable.
Update the Variable/Property when you are changing the Folder.
public System.Collections.Generic.List<string> FolderPath
{
get
{
if (ViewState["__FolderPath"] == null)
ViewState["__FolderPath"] = new System.Collections.Generic.List<string>();
(System.Collections.Generic.List<string>)ViewState["__FolderPath"];
}
set
{
ViewState["__FolderPath"] = value;
}
}
public string CurrentPath
{
get
{
//retrun the current path from the List FolderPath. ;
}
}
You can achive this with the TreeView control
You could also look at the oBout TreeView which is an excellent upgrade from the Microsoft Treeview control:
http://www.obout.com/t2/index.aspx

Specify different _Layout.cshtml depending on controller

I created an asp mvc3 project, I want to have a different _Layout.cshtml depending on which controller is selected. This is because with controller 1 it has 2 buttons with the controller2 there will be 3 and with the controller3 there will be 4. Each controller is for a specific type of user, so it depends on the login.
How can i link a controller and its views to another Layout.cshtml, right now there is one layout and it's under the Shared folder.
Thanks!
The View should determine the layout, not the controller.
The Controller should just determine what View is returned.
Then in the top of your view you can specify the layout.
You could add a If statement around it to change it based on your data
#{
if(ViewBag.someValue)
Layout = "~/Views/Shared/_Layout.cshtml";
else
Layout = "~/Views/Shared/_otherLayout.cshtml";
}
At this point since the other one is a bit dated and with mvc 5 , I know you will have some issues with not having brackets. If you wish to use the View to be doing logic then here is a more complete answer.
Controller
public ActionResult Index()
{
ViewBag.Admin = 1;
return View();
}
View
#{
if (ViewBag.Admin == 1)
{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
else
{
Layout = "~/Views/Shared/_Layout.cshtml";
}
}

Resources