Home  >  Article  >  Backend Development  >  Example tutorial of ASP.NET MVC rewriting

Example tutorial of ASP.NET MVC rewriting

零下一度
零下一度Original
2017-07-02 10:35:072061browse

This article mainly introduces ASP.NET MVC in detail to rewrite RazorViewEngine to implement multi-theme switching. It has certain reference value. Interested friends can refer to

in ASP.NET MVC There are generally two ways to switch themes in China, one is by switching the css and js references of the skin, and the other is by rewriting the view engine. It is more flexible by rewriting the view engine, because I can not only have different layouts and styles under different themes, but also make the data items displayed under different themes inconsistent, which means that I can add personalized content under certain themes. thing.

In this article, I will demonstrate by rewriting the view engine. Before doing this, I assume that you already have some basics of MVC. Let's take a look at the effect first:

System After logging in, it is the default theme. When we click to switch the theme, the layout of the menu bar on the left changes, the style of the content on the right also changes, but the address bar remains unchanged. Metronic is used for the interface UI. Although the official website charges a fee, you can always find it for free in China. Official address: http://keenthemes.com/preview/metronic/

##Here, I used sub-regions and sub-modules (Divided by independent business functions), a module is an independent dll. Here, Secom.Emx.Admin and Secom.Emx.History are two independent modules, and the areas Admin and History are created respectively.

You will find that the Areas directory under the Secom.Emx.Admin model is exactly the same as the directory in Secom.Emx.WebApp. In fact, I initially did not want to add it to the module Add any View to the project, but it is added for the convenience of independent deployment.

Right-click the project Secom.Emx.Admin, select "Properties" - "Generate Event" and 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, copy the Views in the project to the specified directory of the Secom.Emx.WebApp project.

Area

Configuration fileI placed it in Secom.Emx.WebApp. In fact, you can place it in a class library project independently, because the registration area After routing, the project will eventually look for all those in the bin directory that inherit the AreaRegistration class, and then let WebApp reference this class library project. The Secom.Emx.WebApp project adds references to Secom.Emx.Admin and Secom.Emx.History.

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 the

namespace and the ## added later #namespaces:new string[1] { "Secom.Emx.Admin.Areas.Admin.Controllers" }, this namespace is the independent module Secom. Emx.AdminThe namespace where the following controller is located. 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 first look at the original

constructor of RazorViewEngine

as follows:

public RazorViewEngine(IViewPageActivator viewPageActivator) 
  : base(viewPageActivator) 
 { 
  AreaViewLocationFormats = 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" 
  }; 
  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}.cshtml", 
   "~/Views/Shared/{0}.vbhtml" 
  }; 
  
  FileExtensions = new[] 
  { 
   "cshtml", 
   "vbhtml", 
  }; 
 }

Then create a new CustomRazorViewEngine that inherits from RazorViewEngine and rewrites the routing rules of View. Since the routing rules can be rewritten, it means that you can define the rules arbitrarily and then abide by the rules you define. That's it. It should be noted that you should pay attention to the order in the routing array. When searching for views, they are searched in order. When a view is found, it will be returned immediately and will not match subsequent routing rules. In order to improve the efficiency of route search, I deleted all vbhtml routing rules here, because I use C# language in the entire project.

using System.Web.Mvc;

namespace Secom.Emx.WebApp.Helper
{
 public class CustomRazorViewEngine : RazorViewEngine
 {
  public CustomRazorViewEngine(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",
    "~/themes/"+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}/Views/{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}.cshtml",
  "~/Views/Shared/{0}.cshtml"
 };

    FileExtensions = new[]{"cshtml"};
   }

  }
 }
}

After rewriting, our routing rules will be like this: when no topic is selected, the original routing will be used Rules, if a topic is selected, the rewritten routing rules are used.

New routing rules: When a theme is selected, search first for themes/theme name/views/Areas/area name/controller name/view name.cshtml. If not found, follow the default Routing rules to find, that is Areas/area name/Views/controller name/view name.cshtml

切换主题View代码:


<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 class="hidden-sm hidden-xs">切换主题 </span> 
      <i class="fa fa-angle-down"></i>
     </button>
     <ul class="dropdown-menu" role="menu">
      <li>
       <a href="javascript:setTheme(&#39;default&#39;)">
        <i class="icon-docs"></i> 默认主题
       </a>
      </li>
      <li>
       <a href="javascript:setTheme(&#39;Blue&#39;)">
        <i class="icon-tag"></i> 蓝色主题
       </a>
      </li>
     </ul>
    </p>
  <script type="text/javascript">
   function setTheme(themeName)
   {
    window.location.href = "/Home/SetTheme?themeName=" + themeName + "&href=" + window.location.href;
   }
</script>

用户登录成功的时候,从Cookie中读取所选主题信息,当Cookie中没有读取到主题记录时,则从Web.config配置文件中读取配置的主题名称,如果都没有读取到,则说明是默认主题,沿用原有的视图引擎规则。

在后台管理界面,每次选择了主题,我都将主题名称存储到Cookie中,默认保存一年,这样当下次再登录的时候,就能够记住所选的主题信息了。


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类:


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;
    }
    //模板风格
    _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 above is the detailed content of Example tutorial of ASP.NET MVC rewriting. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn