asp.net MVC把Areas区域绑定成二级域名

先分析需求

在MVC项目中,我们如果有两个Areas。比如Test和DEMO。我们的访问地址应该是

http://localhost:8098/test

http://localhost:8098/demo

如果我们绑定域名后想实现这样访问

http://test.abc.com:8098/

http://demo.abc.com:8098/

这个问题的相关解决办法倒是不少,比如http://www.cnblogs.com/jobily/archive/2011/10/09/2204800.html。可惜都是破坏了原来项目的结构,对于已经上线的项目不太适用。

本文的解决办法实在不破坏原来的结构之上,在原来的Areas里面重新绑定新的路由规则,重写基类路由 RouteBase的GetRouteData方法达到绑定二级域名,访问Areas的方法。

前期准备工作你需要先修改本地host文件,绑定一些二级域名。比如

127.0.0.1 demo.abc.com

127.0.0.1 test.abc.com

首先新建 AreaDomainRegistrationContext类。

public class AreaDomainRegistrationContext
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="_domainName">子域名 如:www.xxx.com 可以传 abc</param>
        public AreaDomainRegistrationContext(AreaRegistrationContext _context, string _domainName)
        {
            domainName = _domainName; context = _context;
        }
        private string domainName; private AreaRegistrationContext context;
        private RouteCollection Routes
        {
            get
            {
                if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName))
                {
                    DomainRouteTable.DomainRoutes[domainName] = new RouteCollection();
                }
                return DomainRouteTable.DomainRoutes[domainName];
            }
        }

        public Route MapRoute(string name, string url, object defaults, object constraints = null, string[] namespaces = null)
        {
            if (namespaces == null && context.Namespaces != null)
            {
                namespaces = context.Namespaces.ToArray();
            }

            Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
            route.DataTokens["area"] = context.AreaName;
            route.DataTokens["UseNamespaceFallback"] = false;
            route.DataTokens["SubDomain"] = domainName;
            return route;
        }
    }

DomainRouteTable类里面有一个静态属性DomainRoutes。主要存储域名和路由之间的存储关联。

 public class DomainRouteTable
    {
        private static Dictionary<string, RouteCollection> _instance = new Dictionary<string, RouteCollection>();

        public static Dictionary<string, RouteCollection> DomainRoutes
        {
            get
            {
                return _instance;
            }
        }
    }

下面就是重写RouteBase的类了

 public class DomainRoute : RouteBase
    {
        public ResolveDomainName resolveDomainName = DependencyResolver.Current.GetService<ResolveDomainName>();
        public RouteData d = new RouteData(null, new StopRoutingHandler());

        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            string domainName = resolveDomainName.Resolve(httpContext);
            //该主机头没有配置,返回 null 继续查找路由
            if (domainName == null) return null;

            if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) return d;

            var rs = DomainRouteTable.DomainRoutes[domainName];
            RouteData routeData = rs.GetRouteData(httpContext);
            if (routeData == null) return d;
            return routeData;
        }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            string domainName = resolveDomainName.Resolve(requestContext.HttpContext);

            if (domainName == null) return null;
            if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) return null;

            var rs = DomainRouteTable.DomainRoutes[domainName];
            VirtualPathData vpd = rs.GetVirtualPathForArea(requestContext, values);
            return vpd;
        }
    }

ResolveDomainName主要映射Areas和域名之间的关系,可以根据Areas查找到域名。

 public class ResolveDomainName
    {
        public static Dictionary<string, string> DomainMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        public string Resolve(HttpContextBase httpContext)
        {
            string key = httpContext.Request.Headers["host"];
            string value;
            if (DomainMap.TryGetValue(key, out value)) { return value; }
            else return null;
        }
    }

接下来在Global文件的里面的Application_Start方法里面的第一行加入一下代码

RouteTable.Routes.Add(new DomainRoute());
ResolveDomainName.DomainMap.Add("demo.abc.com:8098", "demo1");

ResolveDomainName.DomainMap.Add("test.abc.com:8098", "Test");

这样就可以绑定多个域名,后面的demo1和Test可以不和areas的名称相等,这里这是一个key而已。

接着在Areas区域里面绑定路由的地方加入一下代码

 var context2 = new AreaDomainRegistrationContext(context, "Test");

            context2.MapRoute(
                name: "Test_default",
                url: "{controller}/{action}",
                defaults: new { controller = "Home", action = "index" },
               namespaces: new string[] { "WebApplication1.Areas.Test.Controllers" });

代码看起来是这样的,这样并不影响之前的访问,还是可以通过areas的方式访问的

同理demo区域也添加代码。

接着编译我们的项目,就可以用demo.abc.com:8098来访问了,是不是很简单。

访问后的效果

本文参考文章地址

https://www.cnblogs.com/hitearth/p/6848788.html

原文地址:https://www.cnblogs.com/Playfunny/p/9875342.html

时间: 2024-08-28 15:14:07

asp.net MVC把Areas区域绑定成二级域名的相关文章

ASP.NET MVC学习之模型绑定(1)

一.前言 下面我们将开始学习模型绑定,通过下面的知识我们将能够理解ASP.NET MVC模型的模型绑定器是如何将http请求中的数据转换成模型的,其中我们重点讲述的是表单数据. 二.正文 1.简单类型绑定 学过一定ASP.NET MVC都会为这个特点所骄傲,就是能够将表单中与同名的参数映射,这相比操作ASP.NET控件来获取值轻便了许多,但是正如上面所说的那样要同名(大小写不区分),下面我们会讲述如何自己去指定. 首先我们在HomeController(如果不存在则创建)中获取表单中的值并显示:

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中使用区域来方便管理controller和view

在ASP.NET MVC中使用区域来方便管理controller和view 在mvc架构中,一般在controllers和views中写所有控制器和视图, 太多控制器时候,为了方便管理,想要将关于person的所有控制器放在一个文件夹里面,这样就容易查看和管理. 这时候在WEB下面创建一个Areas文件夹.(和Controllsers文件夹同级) 然后在Areas里面右键选择新建区域. 会自动创建一个路由信息,和web.comfig还有controllers文件夹等. 这时候就可以很清晰的管理和

ASP.NET MVC使用Areas后怎样获取Area(区域)的名称

写此随笔,目的只为今后在ASP.NET MVC项目中再用到Area(区域)时作为备查. 获取当前Area(区域)名称的方法是: ViewContext.RouteData.DataTokens["area"] 这样,我就可以通过下面三个语句,分别获取用户当前访问的Area.Controller和Action string areaName = filterContext.RouteData.DataTokens["area"] == null ? "&qu

ASP.NET MVC 4 (九) 模型绑定

模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Inde

ASP.NET MVC学习之模型绑定(2)

3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了很多过程中的控制,所以我们就需要使用手工的方式进行绑定.下面我们通过一个例子来说明,首先打开Views/Home/Index.cshtml页面,并输入如下代码: 1 @{ 2 ViewBag.Title = "Index"; 3 } 4 5 @if (TempData.ContainsKey("msg")) 6 { 7 <h1> 8 @TempDa

[转]ASP.NET MVC 4 (九) 模型绑定

本文转自:http://www.cnblogs.com/duanshuiliu/p/3706701.html 模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: n

asp.net mvc 中的模型绑定

在asp.net MVC 应用程序, 表单提交的数据通过模型绑定将数据从View传递到控制器中.使用模型绑定显然比Request.Form["Price"] ,Decimal.Parse(Request.Form["Price"] )还需要手动类型转换要要方便很多. 模型绑定有两种,隐式绑定和显式绑定. 1.隐式模型绑定.先将表单值转化为CLR 类型,然后以表单字段name名称,value值参数传递到Action中.为了防止过度提交,使用Bind(Include)属

在ASP.NET MVC中实现区域或城市选择

每次在"万达影城"网上购票总会用到左上角选择城市的功能.如下: 今天就在ASP.NET MVC中实现一下.我想最好的方式应该是写一个插件,但自己在这方面的功力尚欠缺,如果大家在这方面有好的解决方案,希望在这一起交流,那将会更好. 大致思路如下:○ 点击"更换"弹出div,用bootstrap来实现○ div中的tabs,用jqueryui来实现○ tab项中的城市,用jquery.tmpl.min.js模版来实现 有关城市的Model: public class C