将子域名请求路由到MVC区域

写了个扩展,分享给需要的朋友。

0x01 使用方法

在mvc区域中的{xxxx}AreaRegistration.cs文件中,如ProjectsAreaRegistration.cs

<pre>

<code>

using Dsvisual.Extensions;

namespace Dsvisual.WebApp.Areas.Projects
{
    public class ProjectsAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "Projects";
            }
        }

public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapSubdomain("projects", true);
        }
    }
}

</code>

</pre>

0x02 扩展功能源码

<pre><code>

/// <summary>
    /// an extension for map subdomain request to a mvc area
    /// </summary>
    public static class RouteExtension
    {
        /// <summary>
        /// 创建该区域(Area)的路由并将子域名(subdomain)的请求映射到该区域
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="subdomain">子域名</param>
        /// <param name="allowShortUrl">是否启用短地址(当请求地址位于默认控制器时支持控制器路径省略)</param>
        public static void MapSubdomain(this AreaRegistrationContext ctx, string subdomain, bool allowShortUrl)
        {
            ctx.Routes.MapSubdomain(subdomain, ctx.AreaName, ctx.Namespaces.ToArray(), allowShortUrl);
        }

/// <summary>
        /// 映射子域名到对应的区域
        /// map the subdomain requests to the specific mvc Area
        /// </summary>
        /// <param name="routes"></param>
        /// <param name="subdomain">子域名,支持多级 如admin.info.domain.com 则子域名为admin.info</param>
        /// <param name="areaName">MVC Area名称</param>
        /// <param name="namespaces">MVC Area所在的命名空间</param>
        /// <param name="allowShortUrl">是否启用短地址(当请求地址位于默认控制器时支持控制器路径省略)</param>
        private static void MapSubdomain(this RouteCollection routes, string subdomain, string areaName, string[] namespaces, bool allowShortUrl)
        {
            var prefix = areaName + "_";
            var defaults = new { controller = "home", action = "index", id = UrlParameter.Optional };

bool flag = namespaces == null || namespaces.Length == 0;
            var dataTokens = new { area = areaName, Namespaces = namespaces, UseNamespaceFallback = flag };

object constraints = null;

//通过配置两个路由来映射短路由和标准路由
            //这里URL不带路由前缀目的是避免映射为二级域名后Html.ActionLink等输出路由前缀
            //因为MVC区域默认是Projects/{controller}/{action}/{id}这样的格式,
            //这样会导致Html.ActionLink等生成project.domain.com/project/home/index这样的路径
            //而我们需要的是project.domain.com/home/index这样的格式
            if (allowShortUrl)
            {

//短路径输出支持路由默认控制器设置和当前调用的控制器相同的情况
                //比如默认值设置为{controller="home",action="index"}
                //当请求地址为projects.domain.com/details?id=5这样的地址时
                //短路径可以将该请求解析到projects区域下HomeController的Details动作上
                var shortUrl = new Route("{action}/{id}", new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), new MvcRouteHandler());
                var shortUrlLocal = new Route(areaName + "/{action}/{id}", new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), new MvcRouteHandler());
                var shortUrlRoute = new SubdomainRoute(subdomain, areaName, shortUrl, shortUrlLocal);
                routes.Add(prefix + "shortUrl", shortUrlRoute);
            }

var standard = new Route("{controller}/{action}/{id}", new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), new MvcRouteHandler());
            var standardLocal = new Route(areaName + "/{controller}/{action}/{id}", new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), new MvcRouteHandler());
            var standardRoute = new SubdomainRoute(subdomain, areaName, standard, standardLocal);
            routes.Add(prefix + "standard", standardRoute);
        }

/// <summary>
        /// 子域名路由到Area
        /// </summary>
        internal class SubdomainRoute : Route
        {
            public Route LocalRoute { get; private set; }
            public string LowercasedSubdomain { get; private set; }
            public string LowercasedAreaName { get; set; }
            public SubdomainRoute(string subdomain, string areaName, Route targetRoute, Route localRoute)
                : base(targetRoute.Url, targetRoute.Defaults, targetRoute.Constraints, targetRoute.DataTokens, targetRoute.RouteHandler)
            {
                this.LocalRoute = localRoute;
                this.LowercasedSubdomain = subdomain.ToLowerInvariant();
                this.LowercasedAreaName = areaName.ToLowerInvariant();
                //在缺失controller的默认值设定中补充一个controller默认值,否则MvcStandardRoute获取不到路由数据
                if (!this.Defaults.ContainsKey("controller"))
                {
                    this.Defaults["controller"] = "home";
                }
            }

public override RouteData GetRouteData(HttpContextBase httpContext)
            {
                //对于通过localhost或127.0.0.1访问的,SubdomainRoute相当于无效状态
                if (httpContext.Request.IsLocal && httpContext.Request.Url.IsLoopback)
                {
                    return LocalRoute == null ? null : LocalRoute.GetRouteData(httpContext);
                }
                var host = httpContext.Request.Url.Host.ToLowerInvariant();
                if (host.StartsWith(LowercasedSubdomain))
                {
                    var rest = host.Substring(LowercasedSubdomain.Length, host.Length - LowercasedSubdomain.Length);
                    if (rest.Count(x => x == ‘.‘) == 2)
                    {
                        var data = base.GetRouteData(httpContext);
                        //if (data == null)
                        //{
                        //    data = new RouteData(this, this.RouteHandler);
                        //    if (Defaults != null)
                        //    {
                        //        foreach (KeyValuePair<string, object> item in Defaults) //controller action index
                        //        {
                        //            if (!data.Values.ContainsKey(item.Key))
                        //                data.Values[item.Key] = item.Value;
                        //        }
                        //    }
                        //    if (DataTokens != null)
                        //    {
                        //        foreach (var item in DataTokens) //Namespaces,area,UseNamespaceFallback
                        //        {
                        //            if (!data.DataTokens.ContainsKey(item.Key))
                        //                data.DataTokens[item.Key] = item.Value;
                        //        }
                        //    }
                        //}
                        //data.DataTokens["area"] = this.LowercasedAreaName;
                        return data;
                    }
                }
                return null;
            }

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
            {
                if (requestContext.HttpContext.Request.IsLocal && requestContext.HttpContext.Request.Url.IsLoopback)
                {
                    return LocalRoute == null ? null : LocalRoute.GetVirtualPath(requestContext, values);
                }
                var virturalPathData = base.GetVirtualPath(requestContext, values);
                return virturalPathData;
            }
        }
    }

</code></pre>

时间: 2024-08-01 13:30:36

将子域名请求路由到MVC区域的相关文章

子域名查询技术

子域名查询是渗透测试中的重要一环,收集尽可能多的子域名就是尽可能地扩大我们的攻击面和了解网络内部结构. 子域名保存位置 利用点 具体用法 DNS服务器 区域传送漏洞 dig @ns.dnsdomain.com target.com axfr 主站链接 网站爬虫 百度site:target.com 被动解析 字典枚举解析 fierce -dns target.com [-wordlist wordlist.txt] 第三方数据库 调用第三方数据库接口 subdomain.chaxun.la.pyt

MVC区域小结

MVC3一直在学习,项目中有的时候也会用到,博客园也一直逛,想写点什么东西,可惜我这个人平时都很懒,理论层面的东西自己写不来,还是来点实际的简单入门的博客,对自己总结能力是一种提升,当然也希望对没有使用过区域的人有所帮助. 为什么要有区域? MVC本身提倡的就是关注点分离,控制器控制业务逻辑,模型用于读取数据,视展示展示页面,这样不管是对于开发者本身还是对于后来维护项目的开发者来说都是有极大好处的,能很开熟悉项目的业务,而不会像层次不清晰,代码不规范,逻辑混乱的项目,提升开发效率.但是当项目本身

MVC区域使用

新建项目 Main: 添加一个MVC5控制器并添加index视图:(HomeController) Views/Home/Index.cshtml内容: @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title&g

小米范工具系列之九:小米范子域名收集工具

小米范子域名收集工具为一款收集子域名(二级域名.三级域名.四级域名)的工具. 工具的工作流程如下: // 1.获取常用记录类型.MX NS SOA// 2.测试每个dns服务器的区域传送.获取泛域名解析ip列表加入黑名单(也可手动输入黑名单ip).// 3.通过搜索引擎.获取其他接口查询二级域名(百度.必应.netcraft,可设置爬取线程也爬取条数)// 4.通过字典爆破二级域名(可自定义线程数即字典).// 5.获取上面几步收集的域名对应的ip地址列表.// 6.反查(爱站)上一步得到的ip

记录学习MVC过程,MVC区域母版页(七)

1.MVC的区域就是一个小的mvc,区域路由高于普通的路由 mvc区域自带m,v和c,可以把产品,会员,新闻,文件多的时候,可以用多个区域分割项目成小项目 2.渲染局部视图和局部action  (ifram方式不会被蜘蛛爬到,不利于SEO) @{ //Html.RenderPartial("About"); //只渲染了about的页面,数据不会被加载 Html.RenderAction("About");//页面和controller里传过来的数据都被渲染了 }

MVC 区域模块

mvc4.0新增的area区域机制,可以协助你在架构较为大型的项目,让独立性较高的部分功能独立成一个MVC子网站,以降低网站与网站之间的耦合性,也可以通过area的切割,让多人同时开发同一个项目时候,能够减少互相冲突的机会. 在mvc项目中不能有两个同名的控制器,即使你有区分不同的命名空间可以正常编译,但实际上在运行时仍然出错,除非在app_start/RouteConfig文件中通过mapRoute方法新增网址路由的设置,并明确指定命名空间,才能让此功能正常运行. 添加区域 项目上单击右键 添

网站后端_Python+Flask.0012.FLASK域名相关之域名与动态子域名实现?

域名设置: 说明: SERVER_NAME内置属性的设置会影响全局URL,它主要有两个作用,第一个作用是在请求上下文之外生成绝对URL,当然如果设置也会影响请求上下文内的绝对URL,第二个作用是用于子域名的支持 #!/usr/bin/env python # -*- coding: utf-8 -*- """ # # Authors: limanman # 51CTOBG: http://xmdevops.blog.51cto.com/ # Purpose: # "

003. Asp.Net Routing与MVC 之一: 请求如何到达MVC

前言 本文用到的基础知识:URL.HttpModule 与 HttpHandler.IIS7.0的请求处理过程. URL      参见<基础URL>, HttpModule与HttpHandler请读<HttpModule .HttpHandler> IIS7.0的请求处理过程请读<IIS7的><IIS架构> OK,现在我们来看请求如何到达MVC: 一.请求如何到达Asp.Net Routing 我们知道IIS网站的配置可以分为两个块:全局 Web.Con

flask中的蓝图与子域名实现

内容: 1.flask中的蓝图 2.flask子域名实现 1.flask中的蓝图 一个大型项目中视图比较多,如果仅仅是写在app.py中不方便管理,蓝图就可以做到分功能分目录结构 (1)什么是蓝图 蓝图:用于实现单个应用的视图.模板.静态文件的集合. 蓝图就是模块化处理的类 简单来说,蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能. 在Flask中,使用蓝图可以帮助我们实现模块化应用的功能. (2)蓝图的运行机制 蓝图是保存了一组将来可以在应用对象上执行的操