Example tutorial for ASP. NET MVC rewrite

Source: Internet
Author: User
This article is mainly for you to introduce the ASP. NET MVC rewrite Razorviewengine to achieve multi-theme switching, with a certain reference value, interested in small partners can refer to

There are two ways to implement a theme in ASP. One is to switch the skin's CSS and JS references, one by rewriting the view engine. The way to rewrite the view engine is more flexible because I can not only lay out and style differently under different topics, but also make it inconsistent with the data entries displayed under different topics, which means you can add something personalized underneath some of the topics.

I'll show you how to do this by rewriting the view engine, before I assume that you already have some of the basics of MVC, and we'll look at the effect first:

After the system login is the default theme, when we click the switch theme, the left menu bar layout changed, the right side of the content style has changed, and the address bar is unchanged. Interface UI with the Metronic, although the official website is charged, but in the celestial, can always find free. Official address: http://keenthemes.com/preview/metronic/

Here, I used the sub-region, sub-module (according to separate business functions division), a module is a separate DLL, Here Secom.Emx.Admin and Secom.Emx.History are two separate modules, and the region admin and history are created separately.

You will find that the areas directory below the Secom.Emx.Admin model is exactly the same as the directory in the SECOM.EMX.WEBAPP, but I did not initially want to add any view to the module project, but it was added to facilitate standalone deployment.

Right-click the project Secom.Emx.Admin, select Properties--build event to add the following code:


Xcopy/e/r/y $ (ProjectDir) Areas\admin\views $ (solutiondir) secom.emx.webapp\areas\admin\views

This command is very simple, in fact, when compiling the project Secom.Emx.Admin, the project views are copied to the SECOM.EMX.WEBAPP project under the specified directory.

Zone profile I put in the Secom.Emx.WebApp, in fact, you can completely separate into a class library project, because after the registration area is routed, the project will eventually look for the bin directory under all inherited the Arearegistration class, and then let WebApp reference this class library project, secom . The Emx.webapp project adds references to Secom.Emx.Admin, Secom.Emx.History.

The Adminarearegistration code is as follows:


Using System.web.mvc;namespace secom.emx.webapp{public class adminarearegistration:arearegistration  {  public override string AreaName   {   get    {    return ' Admin ';   }  }  public override void Registerarea (AreaRegistrationContext context)   {   context. MapRoute (    "Admin_default",    "Admin/{controller}/{action}/{id}",    new {action = "Index", id = Urlparameter.optional},    namespaces:new string[1] {"Secom.Emx.Admin.Areas.Admin.Controllers"}   );}}  

Note Namespaces and namespaces added later :New string[1] {"Secom.Emx.Admin.Areas.Admin.Controllers"} , this namespace is the namespace where the controller under the standalone module Secom.Emx.Admin .

The Historyarearegistration code is as follows:


Using System.web.mvc;namespace secom.emx.webapp{public class historyarearegistration:arearegistration  {  public override string AreaName   {   get    {    return ' history ';   }  }  public override void Registerarea (AreaRegistrationContext context)   {   context. MapRoute (    "History_default",    "History/{controller}/{action}/{id}",    new {action = "Index", id = Urlparameter.optional},    namespaces:new string[1] {"Secom.Emx.History.Areas.History.Controllers"}   );}}  

Let's look at the original constructor of Razorviewengine as follows:


Public Razorviewengine (Iviewpageactivator viewpageactivator): Base (viewpageactivator) {areaviewlocationformats = NE W[] {"~/areas/{2}/views/{1}/{0}.cshtml", "~/areas/{2}/views/{1}/{0}.vbhtml", "~/areas/{2}/views/shared/{0}.csh   Tml "," ~/areas/{2}/views/shared/{0}.vbhtml "}; Areamasterlocationformats = new[] {"~/areas/{2}/views/{1}/{0}.cshtml", "~/areas/{2}/views/{1}/{0}.vbhtml", "~/   Areas/{2}/views/shared/{0}.cshtml "," ~/areas/{2}/views/shared/{0}.vbhtml "};    Areapartialviewlocationformats = new[] {"~/areas/{2}/views/{1}/{0}.cshtml", "~/areas/{2}/views/{1}/{0}.vbhtml",     "~/areas/{2}/views/shared/{0}.cshtml", "~/areas/{2}/views/shared/{0}.vbhtml"};    Viewlocationformats = new[] {"~/views/{1}/{0}.cshtml", "~/views/{1}/{0}.vbhtml", "~/views/shared/{0}.cshtml",   "~/views/shared/{0}.vbhtml"}; Masterlocationformats = new[] {"~/views/{1}/{0}.cshtml", "~/views/{1}/{0}.vbhtml", "~/views/shared/{0}.cshtml" ,    "~/views/shared/{0}.vbhtml"}; Partialviewlocationformats = new[] {"~/views/{1}/{0}.cshtml", "~/views/{1}/{0}.vbhtml", "~/views/shared/{0}.cs     HTML "," ~/views/shared/{0}.vbhtml "};  Fileextensions = new[] {"cshtml", "vbhtml",}; }

Then the new customrazorviewengine inherits from the Razorviewengine, overriding the view's routing rules, since it is possible to rewrite the routing rules, which means that you can define the rules arbitrarily and then follow your own defined rules. It is important to note that the order in the routing array, when looking for a view, is looked up in order, and then returns immediately after the view is found and no longer matches the following routing rules. To improve the efficiency of routing lookups, I've removed all vbhtml routing rules here, because I've used the C # language throughout my project.


Using System.web.mvc;namespace secom.emx.webapp.helper{public class Customrazorviewengine:razorviewengine {public Cu Stomrazorviewengine (String theme) {if (!string. IsNullOrEmpty (Theme)) {Areaviewlocationformats = new[] {//themes "~/themes/" +theme+ "/views/areas/{2}/{ 1}/{0}.cshtml "," ~/themes/"+theme+"/shared/{0}.cshtml "" ~/areas/{2}/views/{1}/{0}.cshtml "," ~/Areas/{2}/Views/    Shared/{0}.cshtml "}; Areamasterlocationformats = new[] {//themes "~/themes/" +theme+ "/views/areas/{2}/{1}/{0}.cshtml", "~/theme s/"+theme+"/views/areas/{2}/shared/{0}.cshtml "," ~/themes/"+theme+"/views/shared/{0}.cshtml "," ~/Areas/{2}/Views    /{1}/{0}.cshtml "," ~/areas/{2}/views/shared/{0}.cshtml "}; Areapartialviewlocationformats = new[] {//themes "~/themes/" +theme+ "/views/shared/{0}.cshtml", "~/Areas/{2}/V    Iews/{1}/{0}.cshtml "," ~/areas/{2}/views/shared/{0}.cshtml "}; Viewlocationformats = new[] {//themes "~/themes/" +theme+ "/viewS/{1}/{0}.cshtml "," ~/views/{1}/{0}.cshtml "," ~/views/shared/{0}.cshtml "}; Masterlocationformats = new[] {//themes "~/themes/" +theme+ "/views/shared/{0}.cshtml", "~/views/{1}/{0}.cshtml    "," ~/views/shared/{0}.cshtml "}; Partialviewlocationformats = new[] {//themes "~/themes/" +theme+ "/views/shared/{0}.cshtml", "~/Views/{1}/{0}.cs    HTML "," ~/views/shared/{0}.cshtml "};   Fileextensions = new[]{"cshtml"}; }  } }}

After rewriting, our routing rules will be the following: When the subject is not selected, the original routing rule is followed, and if the theme is selected, the overridden routing rule is used.

New routing rule: When a theme is selected, first find the thems/topic name/views/areas/Zone name/Controller name/view name. cshtml, if not found, then follow the default routing rules to find, that is, the areas/zone name/views/ Controller name/view name. cshtml

Toggle Theme View Code:


<p class= "Btn-group" > <button type= "button" class= "Btn btn-circle Btn-outline Red Dropdown-toggle "data-toggle=" dropdown "> <i class=" fa fa-plus "></i> <span CLA     ss= "Hidden-sm hidden-xs" > Toggle theme </span> <i class= "fa fa-angle-down" ></i> </button>        <ul class= "Dropdown-menu" role= "menu" > <li> <a href= "javascript:settheme (' Default ')" > <i class= "Icon-docs" ></i> default theme </a> </li> <li> <a href= "javascript:    SetTheme (' Blue ') > <i class= "Icon-tag" ></i> Blue theme </a> </li> </ul> </p> <script type= "Text/javascript" > Function SetTheme (themename) {window.location.href = "/home/se   Ttheme?themename= "+ themename +" &href= "+ window.location.href; }</script> 

When the user logs on successfully, the selected subject information is read from the cookie, when the subject record is not read in the cookie, the subject name of the configuration is read from the Web. config profile, and if none is read, then the default theme follows the original view engine rules.

In the background management interface, each time you select a theme, I store the theme name in a cookie, which is saved by default for one year, so that you can remember the selected topic information the next time you log in.


using system;using system.web.mvc;using secom.emx.webapp.helper;using System.Web;using  Secom.emx.common.controllers;namespace secom.emx.webapp.controllers{public class Homecontroller:basecontroller {  String themecookiename = "Theme";   Public ActionResult Index () {viewdata["menu"] = Getmenus ();  return View (); Public ActionResult SetTheme (string themename,string href) {if (!string. IsNullOrEmpty (ThemeName)) {Response.Cookies.Set (new HttpCookie (Themecookiename, themename) {Expires = DateTime.Now.   AddYears (1)}); } else {themename = Request.cookies[themecookiename]. Value?? "".   Trim ();   } utils.resetrazorviewengine (ThemeName); return string. IsNullOrEmpty (HREF)?  Redirect ("~/home/index"): Redirect (HREF); Public ActionResult Login () {string themename = Request.cookies[themecookiename]. Value?? "".   Trim (); if (!string.   IsNullOrEmpty (ThemeName)) {utils.resetrazorviewengine (themename);  } return View (); } }}

Utils class:


Using system.configuration;using system.web.mvc;namespace secom.emx.webapp.helper{public class Utils {  private static string _themename;  public static string ThemeName  {   get   {    if (!string. IsNullOrEmpty (_themename))    {     return _themename;    }    Template style    _themename =string. IsNullOrEmpty (configurationmanager.appsettings["Theme"])? "": configurationmanager.appsettings["Theme"];    return _themename;   }  }  public static void Resetrazorviewengine (String themename)  {   ThemeName = string. IsNullOrEmpty (themename)? Utils.ThemeName:themeName;   if (!string. IsNullOrEmpty (ThemeName))   {    ViewEngines.Engines.Clear ();    VIEWENGINES.ENGINES.ADD (New Customrazorviewengine (ThemeName));   }  } }}

The implementation of the way is simply too simple, I do not know how to express the good, I still write down, convenient for those who need to consult, hope can help you. Because the project introduced a large variety of related documents so that the file is relatively large, the reason cannot upload the source code also hope forgive me!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.