可编辑路由—Asp.NET MVC项目编译后,修改路由配置可动态加载

Asp.NET MVC 应用程序一旦完成部署到线上后,就不能够修改路由配置,只有重新编译应用程序,重新部署到程序集才能够完成,最近在学习过程中看到了一篇博客关于如何更改路由选项后,能够直接运行到已部署的应用程序中。

首先看看我在程序中,解决方案的结构选项,方便学习,,Route文件夹中放的是这次需要的类文件和接口,在控制器中我定义了一个HomeController 在里面定义了Index和Modify两个方法,也在Views文件夹中定义了相应的视图用于测试使用。

1,定义一个IRouteRegistrar.cs 接口,用于编写Routes.cs这个类

/// <summary>
   /// 路由注册接口
   /// </summary>
  public  interface IRouteRegistrar
   {
      void RegistrarRoutes(RouteCollection routes);
   }

2.编写一个Routes.cs 类,并且实现IRouteRegistrar 接口

/// <summary>
    /// Route配置文件,要更改路由在这个文件中更改
    /// </summary>
    public class Routes:IRouteRegistrar
    {
        public void RegistrarRoutes(RouteCollection routes)
        {
            //实现路由注册的方法,改方法编写和RoutesConfig.cs的写法一样
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

3.编写Routes 的扩展类 RouteRegistrationExtensions.cs,用于Routes集合的扩展,方便后续操作

/// <summary>
/// 扩展路由注册方法,方便后续代码编写
/// </summary>
public static class RouteRegistrationExtensions
{
    /// <summary>
    /// 加载路由
    /// </summary>
    /// <param name="routes">要扩展的路由对象</param>
    /// <param name="virtualPath">文件存在的相对路径</param>
    static void ReloadRoutes(this RouteCollection routes, string virtualPath)
    {
        //根据文件创建程序集
        var assembly = BuildManager.GetCompiledAssembly(virtualPath);
        //根据类名反射出类对象  注意:类名需加上类名所在的命名空间
        var registrar = assembly.CreateInstance("MVC路由配置发布后可更改Demo.Routes") as IRouteRegistrar;
        using (routes.GetWriteLock())
        {
            routes.Clear();
            if (registrar !=null)
            {
                //注册路由
                registrar.RegistrarRoutes(routes); 
            }
        }
    }

/// <summary>
    /// 注册路由
    /// </summary>
    /// <param name="routes">要扩展的路由对象</param>
    /// <param name="virtualPath"></param>
    public static void RegisterRoutes(this RouteCollection routes, string virtualPath)
    {
        if (String.IsNullOrEmpty(virtualPath))
        {
            throw new ArgumentException("virtualPath路径不存在");
        }
        routes.ReloadRoutes(virtualPath);
        //调用监听事件
        ConfigFileChangeNotifier.Listen(virtualPath, routes.ReloadRoutes);
    }
}

4.编写一个ConfigFileChangeNotifier.cs 类,用于监听配置文件更改时,进行相应的操作

/// <summary>
   /// 配置文件更改监听类
   /// </summary>
   public class ConfigFileChangeNotifier
   {
       VirtualPathProvider _vpp;
       Action<string> _changeCallback;
       private ConfigFileChangeNotifier(Action<string> changeCallBack)
           : this(HostingEnvironment.VirtualPathProvider, changeCallBack)
       { }

private ConfigFileChangeNotifier(VirtualPathProvider vpp, Action<string> changeCallBack)
       {
           _vpp = vpp;
           _changeCallback = changeCallBack;
       }

/// <summary>
       /// 监听事件(当文件的内容发生改变时,调用action)
       /// </summary>
       /// <param name="virtualPath">文件路径</param>
       /// <param name="action">委托对象</param>
       public static void Listen(string virtualPath, Action<string> action)
       {
           var notifier = new ConfigFileChangeNotifier(action);
           notifier.ListenForChanges(virtualPath);
       }

void ListenForChanges(string virtualPath)
       {
           var virtualPathDependencies = new List<string>();
           virtualPathDependencies.Add(virtualPath);
           CacheDependency cacheDependency = _vpp.GetCacheDependency(
             virtualPath, virtualPathDependencies, DateTime.UtcNow);
           HttpRuntime.Cache.Insert(virtualPath /*key*/,
             virtualPath /*value*/,
             cacheDependency,
             Cache.NoAbsoluteExpiration,
             Cache.NoSlidingExpiration,
             CacheItemPriority.NotRemovable,
             new CacheItemRemovedCallback(OnConfigFileChanged));
       }

void OnConfigFileChanged(string key, object value,
         CacheItemRemovedReason reason)
       {
          //判断是否发生改变
           if (reason != CacheItemRemovedReason.DependencyChanged)
           {
               return;
           }
           _changeCallback(key);
           ListenForChanges(key);
       }
   }

5.需要的工具类已经编写完成,在最后需要在App_Start文件夹中找到RouteConfig.cs类,在RegisterRoutes方法中,注册刚刚编写的代码
public static void RegisterRoutes(RouteCollection routes)
{
    RouteTable.Routes.RegisterRoutes(@"~/Route/Routes.cs");
}

好了,上面的代码编写完成,运行效果如下。

运行程序     这是在原来的路由情况下运行出来的效果,不要关闭运行的应用程序,这是找到应用程序中Route文件夹下的Routes.cs用记事本打开,更改路由配置,重新再浏览器中刷新,默认加载的视图就会发生改变。 这时,就达到了自己想要的效果。

时间: 2024-10-11 03:41:34

可编辑路由—Asp.NET MVC项目编译后,修改路由配置可动态加载的相关文章

从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用ApplicationPart动态加载控制器和视图

标题:从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图作者:Lamond Lu地址:https://www.cnblogs.com/lwqlun/p/11137788.html源代码:https://github.com/lamondlu/Mystique 前言# 如果你使用过一些开源CMS的话,肯定会用过其中的的插件化功能,用户可以通过启用或者上传插件包的方式动态添加一些功能,那么在ASP.NET Core MVC中如

在 ASP.NET MVC 项目中使用 WebForm、 HTML

原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各的优点,我们可能需要同时使用ASP.NET MVC和WebForm.本文介绍了如何在ASP.NET MVC项目中使用WebForm.首先新建一个名为WebForms的文件夹用于存放WebForm,并添加一个Web窗体文件Demo.aspx作为演示. Demo.aspx就简单的输出一句话“It’s a

ASP.NET MVC 及 Areas 简单控制路由

ASP.NET MVC中怎么去控制路由,这个想关的文章很多,我在这里就是自我总结一下,仅供参考. 1.我们新建一个项目,查看RouteConfig.cs,代码如下: 1 public static void RegisterRoutes(RouteCollection routes) 2 { 3 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 4 5 routes.MapRoute( 6 name: "Default&quo

【转】在 ASP.NET MVC 项目中使用 WebForm

ASP.NET MVC和WebForm各有各的优点,我们可能需要同时使用ASP.NET MVC和WebForm.本文介绍了如何在ASP.NET MVC项目中使用WebForm. 首先新建一个名为WebForms的文件夹用于存放WebForm,并添加一个Web窗体文件Demo.aspx作为演示. Demo.aspx就简单的输出一句话"It's a WebForm." 关键步骤在于路由设置.如果你希望WebForms这个文件夹名作为URL的一部分,也就是普通WebForm应用程序的方式来访

AngularJS2 + ASP.NET MVC项目

环境:VS2015, NodeJS:v 6.5, npm: v3.10, AngularJs 2 通过将ASP.NET MVC项目与Angualr 2官网上的quick start整合的过程中遇到些问题. 通过下面的若干配置最终向项目build成功.

jNs 在 ASP.NET MVC 项目中的应用

最近做项目用到 ASP.NET Web Optimizatoin Framework,发现 Sea.js 的依赖加载在 Release 版本下不能很好的工作了--因为 Web.Optimizatoin 合并了所有脚本.同时由于写惯了 Java 程序和 C# 程序,对于没有命名空间概念的 Sea.js 和 RequireJS 也感觉不爽.考虑了下,觉得模块管理其实并不复杂,所以将之前在<ASP.NET MVC4 捆绑(Bundle)技术下的 JavaScript> 中提到的 js-modular

时间:第1周9月16日;主题:初识ASP.NET MVC项目开发(一)

Part I:回顾及提问 ==================== 1. ASP.NET MVC是微软公司.NET平台上的一个______________,它为开发者提供了一种构建结构良好的Web应用程序的方式. 2. 自2007年首次公布预览以来,作为_____________的替代品,ASP.NET MVC的普及度已明显提高,现在很多大型Web应用程序都是使用这一技术构建的. 3. 为了简化软件开发的复杂度,以一种概念简单却又权责分明的架构来贯穿整个软件开发流程,将业务逻辑层与_______

ASP.NET MVC项目里创建一个aspx视图

先从控制器里添加视图 视图引擎选"ASPX(C#)",使用布局或模板页不要选. 在Views\EAV目录里,生成的aspx是个单独的页面,没有代码文件,所以代码也要写在这个文件里. @ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" @ Import Namespace="System" @ Import Namespace="

跟我学ASP.NET MVC之十一:URL路由

跟我学ASP.NET MVC之十一:URL路由摘要: 在MVC框架之前,ASP.NET假定在请求的URLs和服务器硬盘文件之间有直接的关系.服务器的职责是接收浏览器请求,从相应的文件发送输出. 这种方法只能工作于Web表单,每一个ASPX页面既是一个文件,也是一个对应请求的自包含响应.而这对于MVC应用程序来说就无效了,因为请求是由控制器类里的行为方法处理的,而且没有磁盘上一对一关系的文件. ASP.NET平台使用路由系统处理MVC URLs.在这篇文章中,我将向你展示怎样为你的工程使用路由系统