.text urlRewrite介绍。。

1、花絮:
第一次拿到dottext时,开始让我比较觉得比较奇怪的是

一、以floerggyy注册后通过URL:http://x.x.x.x/floerggyy即可进入自己的blog里
(其实忘了以前常做下载页面download.aspx也不过是处理了HttpHandler的虚页面而已,可能是见在.Text兴奋的连这些基本常识都忘了^_^)

二、居然可以拿用户名做用户的唯一标识但在表里面没有找到做为用户名UserName唯一约束的东东(到现在还不清楚在数据库哪个地方设置的,有知道的请指点下)
后来通过重得注册同一用户名查看抛出的异常信息,确认确实在有UserName做为唯一约束的东东。
唉,看来我对数据库一无所知。

...后来决定专写一篇关于URL重写的文章,后来看到dottext的原作者也简单介绍了下urlRewrite,于是这个想法就放弃了。
后来又有一些朋友问dottext关于URL的问题,看来还是写吧
2、配置文件WebConfig.config简单浏览
自定义配置节内容:
 <configSections>
  <section name="BlogConfigurationSettings" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework" />
  <section name="HandlerConfiguration" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework" />
  <section name="SearchConfiguration" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework" />
  <section name="microsoft.web.services" type="Microsoft.Web.Services.Configuration.WebServicesConfiguration, Microsoft.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  <section name="codeHighlighter" type="ActiproSoftware.CodeHighlighter.CodeHighlighterConfigurationSectionHandler, ActiproSoftware.CodeHighlighter" />
 </configSections>

HttpHandler的配置内容:
 <httpHandlers>
  <add verb="*" path="*.asmx" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
   validate="false" />
  <add verb="*" path="Error.aspx" type="System.Web.UI.PageHandlerFactory" />
  <add verb="*" path="*" type="Dottext.Common.UrlManager.UrlReWriteHandlerFactory,Dottext.Common" />
 </httpHandlers>

HttpModule的配置内容:
 <httpModules>
  <add name="UrlReWriteModule" type="Dottext.Common.UrlManager.UrlReWriteModule, Dottext.Common" />
  <add name="EventHttpModule" type="Dottext.Framework.ScheduledEvents.EventHttpModule, Dottext.Framework" />
 </httpModules>

见到一个陌生的项目首先打开它的配置文件看看,这是我的习惯:)
先看看一些重点的配置内容:
看完Web.config中的上述内容熟悉asp.net运行机制的朋友就明白,DotText代码的运行顺序。在这里我再简单重复下
aspnet的内部运行机制(若有不熟悉的朋友请参阅<<ASP.NET FameWork深度历险>>这本书,它对做asp.net开发的朋友很有帮助):
remote client Request---->IIS---->aspnet_isapi.dll-->aspnet_wp.exe-->HttpRuntime--->
HttpModule--->HttpHandler Factory--->HttpHandler--->HttpHandler.ProcessRequest()-->Response client Request
好了,题归正转,client Request首先是被HttpModule截获。当我们请求.text的URL:http://www.cnblogs.com/floerggyy/时,首先是
Dottext.Common.UrlManager命名空间下类UrlReWriteModule的相关方法被调用。
(为什么会被类UrlReWriteModule截获远程请求呢?上面HttpModule配置节的内容不是标明了吗???^_^
明知故问,那么为Dottext.Framework.ScheduledEvents命名空间下的类EventHttpModule会不会截获远程请求?什么时候截获呢?
当然是按先来后顺序了,中国的优良传统都忘了!!!
(其实这样说也是不太准确的,这两个HttpModule确是按顺序执行的但在HttpModule里的一些事件中它们是交叉运行的,好了类EventHttpModule
不在我们的计论范围内在下面的代码就不分析了,有对这块不明白的最好去看下上面推荐的那本书^_^)
3 、URL重写,部分代码分析(这块涉及到众多自定义配置节、HttpModule、HttpHandler的综合应用所以要理顺还是有点麻烦的,要有一小点分析别人代码的耐心。个人认为)
类UrlReWriteModule的方法

private void context_BeginRequest(object sender, EventArgs e){
//它是主要作用是根据请求匹配正则表达式来设置是否重写客户所请求的URL(它默认是重写URL),注意这句代码UrlHelper.SetEnableUrlReWriting(context,false);
 if(ConfigProvider.Instance().IsAggregateSite){
    HttpContext context  = ((HttpApplication)sender).Context;

    string path = context.Request.Path.ToLower();
    int iExtraStuff = path.IndexOf(".aspx");
    if(iExtraStuff > -1 || path.IndexOf(".") == -1) {
     if(iExtraStuff > -1)
     {
      path = path.Remove(iExtraStuff+5,path.Length - (iExtraStuff+5));
     }

     path = regexApplication.Replace(path,string.Empty,1,0);

     if(path == "" || path == "/"  || regexPath.IsMatch(path))
     {
      UrlHelper.SetEnableUrlReWriting(context,false);
     }
     
    }else if(context.Request.Path.ToLower().IndexOf("services") > 0 && context.Request.Path.ToLower().IndexOf(".asmx") > 0 )
    {
     if(AlllowService(context))
     {
      if(context.Request.RequestType!="POST")
      {
       string regexstr=@"/\w+/services/";
       string url=Regex.Replace(context.Request.RawUrl,regexstr,"/services/",RegexOptions.IgnoreCase);
       context.RewritePath(url);
      }
      //string fileName =context.Request; //System.IO.Path.GetFileName(context.Request.Path);
      //context.RewritePath("~/Services/" + fileName);
     }else{
      context.Response.Clear();
      context.Response.End();
     }
    }
   
   }

HttpModule处理完后(这句话并不正确,在这里是这样的)进入HttpHandler Factory,根据HttpHandler的配置内容我们可以马上找到这个类
UrlReWriteHandlerFactory它是处理重写URL请求核心,在这里我详细分析下。
它实现了IHttpHandlerFactory
(看注释就知道这个类是很重要的了)

HttpModule处理完后(这句话并不正确,在这里是这样的)进入HttpHandler Factory,根据HttpHandler的配置内容我们可以马上找到这个类
UrlReWriteHandlerFactory它是处理重写URL请求核心,在这里我详细分析下。
它实现了IHttpHandlerFactory
(看注释就知道这个类是很重要的了)
using System;
using System.Web;
using System.Web.UI;
using System.Text.RegularExpressions;

using Dottext.Framework;
using Dottext.Framework.Components;
using Dottext.Framework.Configuration;

namespace Dottext.Common.UrlManager
{
    /**//// <summary>
    /// Class responisble for figuring out which .Text page to load. By default will load an array of Dottext.UrlManager.HttpHanlder
    /// from the blog.config file. This contains a list of Regex patterns to match the current request to. It also allows caching of the 
    /// Regex’s and Types
    /// </summary>
    public class UrlReWriteHandlerFactory:  IHttpHandlerFactory
    {
        public UrlReWriteHandlerFactory(){} //Nothing to do in the cnstr
        //自定义虚方法从自定义配置节内容反序列化时构造Httphandler
        protected virtual HttpHandler[] GetHttpHandlers(HttpContext context)
        {
            return HandlerConfiguration.Instance().HttpHandlers;
        }

        /**//// <summary>
        /// Implementation of IHttpHandlerFactory. By default, it will load an array of HttpHanlder (Dottext.UrlManager.HttpHandler) from
        /// the blog.config. This can be changed, by overrideing the GetHttpHandlers(HttpContext context) method. 
        /// </summary>
        /// <param name="context">Current HttpContext</param>
        /// <param name="requestType">Request Type (Passed along to other IHttpHandlerFactory’s)</param>
        /// <param name="url">The current requested url. (Passed along to other IHttpHandlerFactory’s)</param>
        /// <param name="path">The physical path of the current request. Is not gaurenteed to exist (Passed along to other IHttpHandlerFactory’s)</param>
        /// <returns>
        /// Returns an Instance of IHttpHandler either by loading an instance of IHttpHandler or by returning an other
        /// IHttpHandlerFactory.GetHanlder(HttpContext context, string requestType, string url, string path) method
        /// </returns>
         //实现接口IHttpHandlerFactory定义的方法
        public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string path)
        {
            //Get the Handlers to process. By defualt, we grab them from the blog.config
            HttpHandler[] items = GetHttpHandlers(context);
            //Dottext.Framework.Logger.LogManager.Log("path",Dottext.Framework.Util.Globals.RemoveAppFromPath(context.Request.Path,context.Request.ApplicationPath));
            //Do we have any?
            if(items != null)
            {
                int count = items.Length;

                for(int i = 0; i<count; i++)
                {
                    //We should use our own cached Regex. This should limit the number of Regex’s created
                    //and allows us to take advantage of RegexOptons.Compiled 
                    //逐个匹配所配置节中定义的请求类型
                    if(items[i].IsMatch(Dottext.Framework.Util.Globals.RemoveAppFromPath(context.Request.Path,context.Request.ApplicationPath)))
                    {
                       //注意这里是关键,注意返回的Httphandler实例
                            //throw new Exception();
                        switch(items[i].HandlerType)
                        {
                            case HandlerType.Page://默认是Page
                                                        
                                return ProccessHandlerTypePage(items[i],context,requestType,url);
                            case HandlerType.Direct:
                                HandlerConfiguration.SetControls(context,items[i].BlogControls);
                                return (IHttpHandler)items[i].Instance();
                            case HandlerType.Factory:
                                //Pass a long the request to a custom IHttpHandlerFactory
                                return ((IHttpHandlerFactory)items[i].Instance()).GetHandler(context,requestType,url,path);
                            default:
                                throw new Exception("Invalid HandlerType: Unknown");
                        }
                    }
                }
            }
            //If we do not find the page, just let ASP.NET take over
            return PageHandlerFactory.GetHandler(context,requestType,url, path);
        }

        private IHttpHandler ProccessHandlerTypePage(HttpHandler item, HttpContext context, string requestType, string url)
        {
            string pagepath = item.FullPageLocation;
            if(pagepath == null)
            {
                pagepath = HandlerConfiguration.Instance().FullPageLocation;
            }
            HandlerConfiguration.SetControls(context,item.BlogControls);
            IHttpHandler myhandler=PageParser.GetCompiledPageInstance(url,pagepath,context);
            return myhandler;
        }

        public virtual void ReleaseHandler(IHttpHandler handler) 
        {

        }
    }
}

要注意它是如何把自定义配置节中的内容拈合成httphandler的实例
把这些理顺后对于理解.text的url重写就不难了....
对上面若有理解不正解的欢迎高手指正

时间: 2024-11-03 21:47:00

.text urlRewrite介绍。。的相关文章

UrlRewriter组件使用说明手册

  UrlRewriter组件使用说明手册 : 所有用户都相同的操作 : 根据用户需求不同而不同 : 用户安装组件后可能出现的问题 UrlRewrite介绍 什么是UrlRewrite? UrlRewri 使用UrlR 为什么使用UrlRewrite: 1) 处理这样的情形:你要更改你的web应用中网页的结构,但你同时也要确保在你移动网页后,那些被人收藏的老URL不会成为死链接. 重写URL 2)其次可以隐藏网站所用的编程语言,还可以提高网站的可移植性. 当网站每个页面都挂着鲜明的.asp/.a

js用闭包遍历树状数组的方法

 这篇文章主要介绍了js中用闭包遍历树状数组的方法,需要的朋友可以参考下 做公司项目时,要求写一个方法,方法的参数为一个菜单数组集合和一个菜单id,菜单数组的格式为树状json,如下面所示: 代码如下:[{"id":28,"text":"公司信息","children":[        {"id":1,"text":"公司文化"},        {"id

js用闭包遍历树状数组的方法_javascript技巧

做公司项目时,要求写一个方法,方法的参数为一个菜单数组集合和一个菜单id,菜单数组的格式为树状json,如下面所示: 复制代码 代码如下: [{"id":28,"text":"公司信息","children":[      {"id":1,"text":"公司文化"},      {"id":2,"text":"招聘计

android 通过重写ScrollView和Listview完成上下滑动选中不同位置标题的效果

    点击这里源码下载 看到了吗?就是这种效果:我再跟大家简单的叙述一下: 头部标题有三个:剧本梗概.剧本正文.剧本介绍. 当ScrollView滑到剧本中的无论哪一个内容标题的时候头部的大标题将被选中并呈现橙色:而三个标题内容下面是ListView的item,嵌在其父控件Scrollview中的. 下面让我们分析一下代码: 布局:activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk

Apache Tika:通用的内容分析工具

项目介绍 Tika是一个内容分析工具,自带全面的parser工具类,能解析基本所有常见格式的文件,得到文件的metadata,content等内容,返回格式化信息.总的来说可以作为一个通用的解析工具.特别对于搜索引擎的数据抓去和处理步骤有重要意义. Tika是一个目的明确,使用简单的apache的开源项目.下图是Tika诞生的一个历史过程. Tika项目之初来源于Nutch项目(大家应该都不陌生),现在是Lucene的子项目,所以也是来源于搜索引擎.其实Nutch这个项目的开发过程中,孕育了不少

基于BootStrap Metronic开发框架经验小结【三】下拉列表Select2插件的使用_javascript技巧

在上篇基于BootStrap Metronic开发框架经验小结[二]列表分页处理和插件JSTree的使用,介绍了数据的分页处理,使用了Bootstrap Paginator插件,另外对树形列表,采用了JSTree插件,本篇继续介绍在编辑页面中常用到的控件Select2,这个控件可以更加丰富传统的Select下拉列表控件,提供更多的功能和更好的用户体验. 1.Select2控件介绍 这个插件是基于Select的扩展插件,能够提供更加丰富的功能和用户体验,它的github官网地址为:https://

Android 沉浸式状态栏及悬浮效果_Android

一.概述 现在大多数的电商APP的详情页长得几乎都差不多,几乎都是上面一个商品的图片,当你滑动的时候,会有Tab悬浮在上面,这样做用户体验确实不错,如果Tab滑上去,用户可能还需要滑下来,在来点击Tab,这样确实很麻烦.沉浸式状态栏那,郭霖说过谷歌并没有给出沉浸式状态栏这个明白,谷歌只说了沉浸式模式(Immersive Mode).不过沉浸式状态栏这个名字其实听不粗,随大众吧,但是Android的环境并没有iOS环境一样特别统一,比如华为rom的跟小米rom的虚拟按键完全不一样,所有Androi

Javascript 代码也可以变得优美的实现方法_javascript技巧

一.简化代码 采用更为简短的写法,不仅可以减少输入的字符数,还可以减少文件大小.大部分采用简单写法的代码,执行效率都有轻微提高. 1.1 简化常用对象定义:使用 var obj = {}; 代替 var obj = new Object(); 使用 var arr = []; 代替 var arr = new Array(); 1.2 精简if语句三元操作符可以有效精简只涉及赋值传值操作的if语句,比如 var score = 60, grade; if (score < 60) { grade

asp.net 控件制作下拉导航菜单

asp教程.net 控件制作下拉导航菜单 今天的一个小测试是老师让用.NET用控件来制作一个拉菜单要求如下: 将鼠标移到父菜单上弹出3个子菜单,而且每个子菜单都有超链接. 以下是我自己做的代码: <asp:Menu ID="Menu1" runat="server" Orientation="Horizontal" Width="100%"         Font-Size="14px" ForeC