In this article, we will learn about Integrating AdminLTE with ASP.NET Core 3.1 MVC or really any other Bootstrap based UI Frameworks completely from scratch. We will also go through about integrating Identity Authentication to our MVC Applicaiton. Also, you will gain quite a lot of practical knowledge on Views, Layouts, Partial Views, Conditional Rendering, Navigation Indicatior and much more.
You can find the source code of this demonstration at my Github.
Disclaimer : This is a pretty huge article with around 3500+ words. Do bookmark this page and continue :D
What we will learn and build?
Here are the Features included.
- Integration with a Third Party Bootrstrap Template.
- Clean usage and seperation of Layouts, Views and Partial Views.
- Integration of Identity Authentication
- Scaffolded Identity
- Conditional Rendering
- Login / Register / Logout and more
The need to Integrate Third-Party Bootstrap UI
If you are back-end developer like me with just OKayish skills with recreating an entire HTML / CSS / JS Template from scratch, you would probably want to look into other options that make your application look 100x more Professional. Now, there are quite a lot of options, including paid templates as well.
For this article, we will use an Open Sourced Dashboard Template that is quite popular.
Here are the advantages of integrating an already built template.
- Proffesional UI
- Already Tested.
- Responsive.
- Would have a bunch of reusable components like datatables, forms, and more so that you donât have to re-invent the wheel.
Whatâs AdminLTE?
AdminLTE is an open sourced Admin Dashboard Template that is built over Bootsrap. It is packed with quite a lot of responsive and commonly used components that are very easily integrated with your webapplications.
To get a better picture, click here to see a demo of AdminLTE in action.
You may notice how premium it already looks. For now, these pages are not bound to any server side applications. They are just plain old HTML files. In this article we will integrate this UI with our ASP.NET Core MVC Application with some clean practices.
Downloading AdminLTE
AdminLTE is completely FREE to use. Follow this link to start downloading. At the time of writing this article, 3.0.5 is the latest version available. Click on the link to Source Code to download the zipped file on to your machine.
Exploring the Folder Structure
Once downloaded, extract the zipped file. Here you will find a bunch of folders and files. We will not have to touch each and every file, rather just a few. I will give you a brief overview on what each folder contains.
- dist/ - This is the distribution folder that contains all the css and js files, mostly all the static files of the application. We will need to copy this folder over to wwrootfolder of our MVC Project later on.
- pages/ - Here you get a list of all pre-made HTML files to refer to. This is quite an important section as it uses all the available components and can be helpful to check out how components are being utilized.
- plugins/ - 3rd party JS plugins like select2, jquery, datatables, etc are contained here. We will need this folder too.
- starter.html - Here we get a minimal setup of the HTML file. We will using this page to generate the _Layout.cshml for our ASP.NET Core MVC Application. I have attached a screenshot below.
Setting up ASP.NET Core MVC Project with Authentication
Letâs create a new ASP.NET Core Application with the Model-View-Controller (MVC) Template. Make sure you select the authentication mode to Individual User Accounts. This enables us to use the built in Authenication (using Microsoft Identity). I will be using Visual Studio 2019 Community.
Now that we have our AdminLTE files and ASP.NET Core Application ready, letâs start integrating them. Before getting started, letâs see how the default layout of ASP.NET Core work.
Understanding Layouts and Partial Views
Build and run the Application. This is the default layout that comes out of the box with ASP.NET Core 3.1 Web Applications.
This is how the page is split into.
- Main Layout Page - This is the master layout defined at /Views/Shared/_Layout.cshtml
- Navigate Panel - Within the master layout,a partial view reference is defined that calls the _LoginPartial.cshtml page.
- Content Body - Here is where the actual content goes.
PS, ASP.NET Core uses .cshtml (Razor markup files) extension for itâs pages.
Now why this kind of seperation?
In ASP.NET Core MVC, you can generate Views (CHTML) via controllers. Imagine a real life application having multiple controllers and views. You really donât want to define the entire HTML for each view do you? Because we already know that we will be having a site-wide common template. So what this Layout concept does is that, you define the layout cshtml just once, and add the content of each other pages dynamically within the layout page.
So, you define the entire HTML Part that essentilaty would be common throughout the application, and you seperate the dynamic content in another cshtml page. This way, we can make the application much more maintainable and reduce the size of the entire application. Get the point?
Letâs examine the file where the default layout is defined. Since we created a MVC templated application, we can find this file at ../Views/Shared/_Layout.cshtml in the solution structure. You can see that this page starts with a HTML tag. This suggests that this is an entire HTML page with all the body and head tags.
Now somewhere at line 33 or so, you would see the following.
@RenderBody
is used to render the content of the child page. When you run the ASP.NET Core application, it navigates to the root of the application, that is , localhost:XXXX/Home and invokes the Index Method in the HomeController (as it is set as the default route). Letâs see what this method contains.
It just returns a view (.cshtml). Rightclick on the View and click Go To View. This will take us to associated CSHTML File.
You will be navigated to Views/Home/Index.cshtml. Here is the content of the page. This is exactly what we saw on the page when we ran the application. Makes sense?
This content is loaded by the @RenderBody
tag, so that on runtime you get the complete web page (including the static HTML content and the dynamic code generated by C#).
Now, letâs talk a bit on partial views. In your _Layout.cshtml page, you may find this somewhere in 20th line or so.
Unlike Views, Partial Views in ASP.NET Core renders the HTML output within another Viewâs rendered output. There can be cases where your applications has components that can be reused anywhere within the application. In our case we have the top Navigation bar that is quite common through the application. You can find the _LoginPartial.cshtml in the shared folder as well.
Integrating AdminLTE with ASP.NET Core
With the basic concepts of Layouts, View and partial Views clear, it will be easier to integrate any 3rd Party HTML Layout to our ASP.NET Core Applications. Letâs proceed.
Copying the Required Resources
As mentioned earlier, AdminLTE is built over Bootstrap. Hence it contains quite a lot of jquery and js integrations as well. We would not be just copying the HTML content, but also the related resources, like css, images, libraries, js files , etc.
In our AdminLTE Folder, Navigate to distcss and copy the content over to the wwwrootcss folder in our Visual Studio. Do the same for the js folder as well.
PS, to copy th contents over, just copy the selected folder/file and go the Visual Studio. Here you may find a wwwroot folder. This is the folder meant to hold the static files of ASP.NET Core applications. Just paste the copied file here with a simple CTRL+V command.
Next copy the entire img folder to the wwwroot folder. Navigate back to the root of the AdminLTE folder and copy thr plugins folder to the wwwroot folder as well.
Note that we will not be using all the plugins in the plugins folder for now. You may need to removed the unused files once you are done with the application to save small space. For now, letâs keep them.
This is how your wwwroot folder would look like after we are done copying the content.
Now that we have all the required resources moved to our application. Letâs wire up the Layout Page.
Adding Layout pages & Partial Views
An Application can have multiple Layout pages. For this tutorial, letâs not disturb the existing _Layout.cshtml page. Rather, letâs build one specifically for AdminLTE.
In the Shared Folder, create a new folder named AdminLTE. Here is where you would want to put all the .cshtml related to AdminLTE.
Before building the layout pages and partial views, letâs decide on how we will seperate the HTML content. Note that we will be using the starter.html page to build the Layout. Open up the starter.html page on your browser.
Here is how we could split up the page into.
- Side Navigation
- Top Navigation
- Body
- Footer
Additionaly we will want to add 2 more partial views that will hold the references to the css and js files respectively. This makes it easier to sort and manage your resource references.
Under the AdminLTE Folder create a new View and name it _Layout.cshtml. Make sure to uncheck the partial view and layout page options.
Next, letâs start adding the partial view files. In the same AdminLTE folder, add a new view and name it _MainNavigation.cshtml. This time, check the âcreate as a partial viewâ option.
Similary, add other partial views with the following file names.
- _TopNavigation
- _Footer
- _Scripts
- _Styles
This way, you can neatly structure you Layouts.
Letâs start adding content to each file. So, now we have the idea of how we will split the HTML. Open up starter.html in a code editor. I use VS Code. The starter.html has over 330 lines of HTML. Letâs move the code one by one.
Scripts. Go to the end of the file. Above the body tag, you can find few of the script reference there. Cut it and Paste it over to _Scripts.cshml. Replace in the starter.html with the following.
Footer. Just above where the scripts were defined, you can find the footer container. Cut this and move to _Footer.cshtml. Add the following instead in the starter.html. We will move the codes from here to the _Layout.cshtml once we are done with the partial views.
Body. You can find a div class âcontentâ. Delete the entire child div which has a class named ârowâ This is where we wuold want to put our @RenderBody tag.
Main Navigation - Search for a class âmain-sidebarâ. Cut it and move it to _MainNavigation.cshtml. Here you have all the sidebar items at once place for you to extend.
Top Navigation - Search for the class âmain-headerâ and move the content over to _TopNavigation.cshtml.
Styles. Below the title tag, you can see a bunch of stylesheet references. Cut and paste to _Scripts.cshtml and Replace with the following instead.
Now, we have moved all the possible componets to partial views. What remains in our code editor would look something like this. Move this to the _Layout.cshtml
Congrats, we have seperated the htmls to layouts and partial views. Now build and run the application. You would see absolutely no change. Why? Because we have not mentioned anywhere to use our new layout, have we?
For this, Navigate to Views/Home/Index.cshtml and mention the layout manually.
After this, run the application again. You would see quite of lot of changes. (which you are probably not happy with :p ). The entire page would be broken. However, you can see that we are able to display the content we passed from the View. Now letâs the fix the page.
Any guesses on why this page is broken? Itâs quite simple if you already have experiences with HTML pages. This is commonly because the page cannot find the stylesheets that contains the styles defined. We copied the styles and scripts to the Partial Views, but we did not changes the references. Letâs change the paths to point to the specifc files in the wwwroot folder.
Open up _Styles.cshtml and modify as below
Open up _Scripts.cshtml and modify as below
Thatâs it. Run the application again.
There you go! You can see that the page starts looking great. The only issue is a broken image reference. You can fix it similarly by going to _MainNavigation.cshtml and fixing the reference issue like we did earlier.
Now, letâs add this layout to the Privacy Page too! Go to Views/Home/Privacy.cshtml add in the following line.
Run the application and navigate to loclhost:xxx/home/privacy. This is what we get.We are all setup now.
Adding Navigation
Letâs add some navigation menu to our _MainNavigation.cshtml. What we need to do is simple. Remove the static paths and add add links to our controller methods. For now, we will add 2 Navigation Items. Home and Privacy.
- Home will be linked to Home/Index
- Privacy page will be linked to Home/Privacy
Line 3 and 10 - image reference fix.
Line 19 - You can see for the navigation Item named âHomeâ , we are linking to the controller âHomeâ and Index actions.
Line 27 - For the Privacy page, we like to the Home Controller and Privvacy method.
Run the application and check.
So thatâs working too. But there is one detail that we are missing. Navigation Indicator. There is no indication in our sidebar about the currently viewed page. For now, since we have just 2 naviagation item, itâs quite fine to check the URL and understand which page we are at right now. But this is not ideal. Letâs fix it first.
Navigation Indicator
For this to work, we need data from our ASP.NET Core regarding the current controller and action method. And based on this we need to change the class of the corresponsing navigation item to active. Active means the current page.
Add a new folder in the root of the project. Name it Helpers. Under it, add a new NavigationIndicatorHelper class.
Here is what this helper class does. It has an extension method with the URLHelper. By this way, you can invoke it in the cshtml page too. It takes in the controller and the action method name and checks it with the current route data. If they match, we retun a string âactiveâ, else null.
Go to _MainNavigation.cshtml. Modify / Add these lines
Run the application. Now, we have got a working navigation indicator. Sweet, yeah?
With that out of the way, as promised, letâs check out how to integrate authentication using the exisitng Identity Authentication.
Integrating the UI with existing Authentication
Let me draw you a scenario. The requirement is that we need to secure a particular view. In our case, we have Index and Privacy pages. Letâs say we keep the Index Page available for everyone. But limit the access to the Privacy page and allow access only if the user is authenticated. We will also want to hide the item from the navigation menu if not authenticated.
If the visitors tries to access the resource (without auth) by navigating directly to ../Home/Privacy, we redirect him to a login page. So this is what we will be doing here. This is quite a practical scenario right?
AdminLTE comes with a default Login and Register page too! Itâs located under ../pages/examples folder as login.html and register.html.
By now you would be quite clear on how to integrate the UI. But there is a catch here. If you examine our ASP.NET Core MVC application, you would no where find a Login or Register page. But we added authentication to the application while creating it, Remember? So how does that work.
Sometime, during the announcment of ASP.NET Core 2.1. Microsoft revealed that the Identity UI (all the pages related to Microsoft Identity) would be moved to a Razor Library. Thus, it works out of the box even though itâs not visible to us.
But, what if we had to do some modification to it? Thatâs where Identity Scaffold comes to play. Follow these steps to bring back the Login and Register Razor Pages for us to modify.
Right click on the Project -> Add New -> New Scaffolded Item.
In this next dialog, select Identity and click Add.
Now, we get to select the required Identity pages. To keep things simple, letâs add only the Login and Registration page. Make sure you select the data class as well. Click Add. Now, Visual Studio does its magic and generate the selected files.
In the background, Visual Studio also makes a DataContext class for you and registers it in the starup services with a default local db.
Once itâs done, you see the following folder with our selected Identity Pages.
Now we will integrate these Views with the login.html and the register.html. It would help you if you do this integration on your own, to help understand the scenarios better. To keep the article compact, i will just the just add the links to the changed files.
- Login.cshtml - https://github.com/iammukeshm/AdminLTE.MVC/blob/master/AdminLTE.MVC/Areas/Identity/Pages/Account/Login.cshtml
- Register.cshtml - https://github.com/iammukeshm/AdminLTE.MVC/blob/master/AdminLTE.MVC/Areas/Identity/Pages/Account/Register.cshtml
These are the resulting page. Pretty neat, yeah?
Enabling Authentication
Now that we have our Identity Pages ready, let us setup our ASP.NET Core Application to enable Authentication.
We will secure all the Controller methods by default. As per as our requirement, we need to allow any random visitor to use the Home/Index method.
Navigate to Startup.cs/ConfigureServices method add these lines.
This will add a new policy to the ASP.NET Core MVC Application that every method needs an authenticated user, unless we define it as [AllowAnonymous]
Now, go to the Home Controller and add [AllowAnonymous] above the Index method. This means that the method can be accessed by anyone.
Thatâs it.Just run the application and check. You would be able to navigate to the Home page without any issues. But when you go to the Privacy page, you will be redirected to the login page. How simple was that.
Authenticated Status Based Menu
We do not want the anonymous user to see the Privacy link in the navigation. To hide the item. go to _MainNavigation.cshtml
Here is the simple logic. We will need to add a condition (if) to check if the current user is authenicated, if yes, display the privacy link. Else, no. Here is how you code it.
Now, there is one more thing that we can add here using the conditional check of authentication. In the side do you see a random image with a random name? Does it make sense to add a similar condition there? Yeah, right? So what we will do is, show the name of the authenticated user . If not authenticated letâs show a âHi, Visitorâ.
Modify the _MainNavigation.cshtml like below.
Build and run the application.
Quite self explanatory, yeah? Finally letâs add the login/register links to the Top Navigation Menu.
Go to _TopNavigation.cshtml and modify the code.
Thatâs all for this guide. Letâs now check if everything works fine. Letâs register a new account.
Ps. we have to apply the migrations yet. While registering for the first time, Visual studio letâs you know about this.
Click on Apply Migrations. Once it is done, You will get a message saying, âTry refreshing the page.â . Refresh the page.
In this page, click on confirm your account. Then Navigate to localhost:xxx/Home
Letâ s login! with the created credentials.
Great, everything works as we intended. Letâs me wind up this really long article :D
Update - Issue with filterizr Plugin for AdminLTE 3.0.5
Recently one of the readers posted an issue in the comments section that he faced while working with AdminLTE 3.0.5. The exception goes something like this.
Build: The module ââ./FilterizrOptions/defaultOptionsââ has no exported member âRawOptionsCallbacksâ. Did you mean âimport RawOptionsCallbacks from â./FilterizrOptions/defaultOptionsââ instead.
With AdminLTE 3.0.5, the filterizr plugin for some reason still has itâs own source code files, which can cause TypeScript errors in Visual Studio if you try to run the project (I didnât face such an issue). If you face the similar issue, kindly remove the plugin from your solution. Delete everything in filterizr folder except for the following files:
- filterizr.min.js
- jquery.filterizr.min.js
- vanilla.filterizr.min.js
AdminLTE Starter Kit for ASP.NET Core 3.1 - Open Source Project
If you are interested in having a starter kit / boilerplate template for AdminLTE ASP.NET Core, take a look at this open-source project.
Summary
In this detailed beginner-friendly guide, We have learnt Integrating AdminLTE with ASP.NET Core 3.1 MVC. We covered several topics inclusing Layouts, Views, PartialViews, Authentication, Identity, Navigation Indicator, and much more. You can check out the complete source code for this demonstration over at my Github. Do not forget to share this article and leave your comments below. Happy Coding :)
Shall we extend this Application by adding more features to it in another articlle? Like jquery datatable, CRUD, Role based Authorization, and more? Leave your opinions about it.