• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    URL重寫及干掉ASP.NET試圖狀態的實現方法

    來源:懂視網 責編:小采 時間:2020-11-27 22:42:45
    文檔

    URL重寫及干掉ASP.NET試圖狀態的實現方法

    URL重寫及干掉ASP.NET試圖狀態的實現方法:1、URL重寫已經很普遍了,但基本上大部分的URL重寫都不支持頁面的相對路徑,所有如果想在已經開發好的項目中添加還是有壓力的,第二就是例如微軟的那個URL重寫是根據正則表達式來處理的,那樣是很好,但也有不足之處,就是不方便定位到某個頁面只能有哪些參數
    推薦度:
    導讀URL重寫及干掉ASP.NET試圖狀態的實現方法:1、URL重寫已經很普遍了,但基本上大部分的URL重寫都不支持頁面的相對路徑,所有如果想在已經開發好的項目中添加還是有壓力的,第二就是例如微軟的那個URL重寫是根據正則表達式來處理的,那樣是很好,但也有不足之處,就是不方便定位到某個頁面只能有哪些參數

    1、URL重寫已經很普遍了,但基本上大部分的URL重寫都不支持頁面的相對路徑,所有如果想在已經開發好的項目中添加還是有壓力的,第二就是例如微軟的那個URL重寫是根據正則表達式來處理的,那樣是很好,但也有不足之處,就是不方便定位到某個頁面只能有哪些參數。
    我覺得要解決的問題有一下幾個:
    1、解決如圖片js等不能使用相對路徑的文件
    2、解決某個頁面能有幾個參數和哪些參數是可選的
    下面就是解決掉這些問題了
      添加處理程序MyHttpModule,下面是我的一個簡單的處理程序(我只是做了一個簡單的,并沒有考慮性能,而且我是寫死的一個url重寫就是重寫成沒有擴展名的)
    代碼如下:

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.IO;
    using System.Text;
    namespace MyClass
    {
    public class MyHttpModule : IHttpModule
    {
    #region IHttpModule 成員
    ///<summary>
    /// 釋放所有資源
    ///</summary>
    public void Dispose()
    {
    }
    ///<summary>
    /// 初始化模塊,并使其為處理請求做好準備
    ///</summary>
    ///<param name="context"> 一個 System.Web.HttpApplication,它提供對 ASP.NET 應用程序內所有應用程序對象的公用的方法、屬性和事件的訪問</param>
    public void Init(HttpApplication context)
    {
    context.AuthorizeRequest += new
    EventHandler(this.BaseModuleRewriter_AuthorizeRequest);
    }
    ///<summary>
    /// 當安全模塊已驗證用戶授權時發生
    ///</summary>
    ///<param name="sender"></param>
    ///<param name="e"></param>
    protected virtual void BaseModuleRewriter_AuthorizeRequest(
    object sender, EventArgs e)
    {
    System.Web.HttpApplication app = (System.Web.HttpApplication)sender;
    Rewrite(app.Request.Path, app);
    }
    ///<summary>
    /// 重寫url
    ///</summary>
    ///<param name="requestedPath">url的虛擬路徑</param>
    ///<param name="app"></param>
    protected void Rewrite(string requestedPath, System.Web.HttpApplication app)
    {
    List<string> qeryString;
    string virtualPath;
    string inputFile = GetInputFile(app.Context, out virtualPath, out qeryString);//獲取到真實的文件信息
    if (System.IO.Path.GetExtension(inputFile) == ".aspx")//如果是aspx文件 那么則把保留重寫的url
    {
    app.Context.RewritePath(requestedPath, string.Empty, string.Empty);//這里查詢參數我沒去處理了,也就是Request.QueryString的信息,如果取qeryString 然后去處理成一個字符串
    return;
    }
    app.Context.RewritePath(virtualPath, string.Empty, app.Context.Request.QueryString.ToString());//其它文件則使用找到的路徑
    }
    ///<summary>
    /// 獲取url對應的絕對路徑和虛擬路徑及查詢參數
    ///</summary>
    ///<param name="context"></param>
    ///<param name="virtualPath">虛擬路徑</param>
    ///<param name="qeryString">查詢參數 如果為null請取HttpContext.Request.QueryString</param>
    ///<returns>url對應的絕對路徑</returns>
    public static string GetInputFile(HttpContext context, out string virtualPath, out List<string> qeryString)
    {
    string executionFilePath = context.Request.AppRelativeCurrentExecutionFilePath.Remove(0, 2);//獲取當前對應的虛擬路徑并干掉“~/”
    string inputFile = context.Request.PhysicalPath;//獲取當前url對于的絕對路徑
    virtualPath = context.Request.AppRelativeCurrentExecutionFilePath;
    qeryString = null;
    List<string> qeryList = new List<string>();
    if (!File.Exists(inputFile))//判斷文件是否存在,也就是沒有被重寫的url獲取使用絕對路徑的資源等等
    {
    bool b = false;
    string fileName;
    string extension;
    string applicationPath = context.Request.PhysicalApplicationPath;//獲取網站的跟目錄
    var tempPath = GetFileInfo(inputFile, out fileName, out extension);
    while (!b)//根據目錄循環獲取有效的文件目錄
    {
    b = File.Exists(tempPath + "\\" + extension);//判斷文件是否存在
    if (tempPath + "\\" == applicationPath)//如果查找到根目錄還沒有查找到那么則不需要在查了
    {
    break;
    }
    if (!string.IsNullOrWhiteSpace(fileName))
    {
    qeryList.Add(fileName);//如果不存在那么這個就是參數 例如http://localhost:4688/WebForm1/2011/ (對應http://localhost:4688/WebForm1.aspx?xxx=2011)
    }
    tempPath = GetFileInfo(tempPath, out fileName, out extension);
    }
    if (b)//如果查找到了就把查找到的路徑復制給
    輸出或返回參數
    {
    inputFile = tempPath + "\\" + extension;
    virtualPath = "~/" + inputFile.Replace(applicationPath, null);
    }
    if (Path.GetExtension(extension) == ".aspx")//如果是asp.net那么則把list復制給輸出參數 qeryString
    {
    qeryString = qeryList;
    }
    }
    return inputFile;
    }
    ///<summary>
    /// 獲取指定目錄+文件是否有效
    ///</summary>
    ///<param name="inputFile">目錄</param>
    ///<param name="fileName"></param>
    ///<param name="extension"></param>
    ///<returns></returns>
    private static string GetFileInfo(string inputFile, out string fileName, out string extension)
    {
    var tempPath = Directory.GetParent(inputFile).FullName;//獲取傳進來目錄的父目錄
    fileName = inputFile.Replace(tempPath + "\\", null);//獲取子目錄名稱
    extension = Path.GetExtension(inputFile);//獲取擴展名
    if (string.IsNullOrWhiteSpace(extension))//如果擴展名為null那么則認為是aspx文件
    {
    extension = fileName + ".aspx";
    }
    else
    {
    extension = fileName + extension;
    }
    return tempPath;
    }
    #endregion
    }
    }

    因為我在處理aspx頁面時還是傳入的重寫后的路徑,所有我們還有添加一個繼承IHttpHandlerFactory的類
    代碼如下:
    代碼如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.IO;
    using System.Web.UI;
    namespace MyClass
    {
    public class MyHttpHandlerFactory:IHttpHandlerFactory
    {
    #region IHttpHandlerFactory 成員
    ///<summary>
    /// 返回實現 System.Web.IHttpHandler 接口的類的實例
    ///</summary>
    ///<param name="context">System.Web.HttpContext 類的實例,它提供對用于為 HTTP 請求提供服務的內部服務器對象(如 Request、Response、Session和 Server)的引用</param>
    ///<param name="requestType">客戶端使用的 HTTP 數據傳輸方法(GET 或 POST)</param>
    ///<param name="url">所請求資源的 System.Web.HttpRequest.RawUrl</param>
    ///<param name="pathTranslated">所請求資源的 System.Web.HttpRequest.PhysicalApplicationPath</param>
    ///<returns>處理請求的新的 System.Web.IHttpHandler 對象</returns>
    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
    List<string> qeryString;
    string virtualPath;
    string inputFile =MyHttpModule.GetInputFile(context, out virtualPath, out qeryString);//這里跟那里是一樣的
    object[] obj = new object[] { };
    Dictionary<string, string> qeryStringDictionary = new Dictionary<string, string>();
    var receiveMembers = System.Web.Compilation.BuildManager.GetCompiledType(virtualPath).GetMember("ReceiveParameters");//獲取訪問當前頁面的所有ReceiveParameters成員 (這個是我自己加的,就是想做成和mvc的那種模式,但可能不是很好)
    System.Reflection.MethodInfo receiveParameters=null;
    if (qeryString != null&&qeryString.Count>0)//如果查找到沒有參數則不去反射了
    {
    foreach (System.Reflection.MemberInfo receiveMember in receiveMembers)//遍歷所有ReceiveParameters成員
    {
    if (receiveMember.MemberType == System.Reflection.MemberTypes.Method)//因為上面獲取到的是成員 但我們要的是方法所有要判斷下
    {
    System.Reflection.MethodInfo methodInfo = receiveMember as System.Reflection.MethodInfo;
    if (methodInfo != null)
    {
    var parameters = methodInfo.GetParameters();//獲取ReceiveParameters方法的所有參數
    int optionalCount = parameters.Count(i => i.IsOptional);//獲取ReceiveParameters參數里面有多少個可選參數
    bool b = qeryString.Count == parameters.Length - optionalCount;
    if (qeryString.Count == parameters.Length || b)//如果當前查詢的參數或ReceiveParameters的所有參數-去可選擇的查詢參數相等
    {
    receiveParameters = methodInfo;//記錄這個方法
    int i = 0;
    obj = new object[parameters.Length];//記錄參數值,到后面調用ReceiveParameters時用
    for (; i < parameters.Length; i++)
    {
    string name = parameters[i].Name;//獲取參數的名稱
    string value = string.Empty;
    if (qeryString.Count > i)//如果ReceiveParameters參數沒到可選參數那么則去查詢的字符串
    {
    value = qeryString[i];
    }
    obj[i] = value;//把查詢的字符串保存起來,到后面調用ReceiveParameters時用
    qeryStringDictionary.Add(name, value);//添加到自定義的集合里面
    }
    break;
    }
    }
    }
    }
    if (receiveParameters == null)//判斷是否已經找到,如果沒找到就把以前找的文件信息全部賦為重寫的文件信息,也就是不存在的
    {
    virtualPath = context.Request.Path;
    inputFile = context.Request.PhysicalPath;
    }
    }
    var temp= System.Web.UI.PageParser.GetCompiledPageInstance(virtualPath, inputFile, context);//編譯頁面
    if (receiveParameters != null)//這個里面的內容其實應該寫到ReleaseHandler里面去的,但我寫在這里了
    {
    System.Web.UI.Page page = (System.Web.UI.Page)temp;
    page.Init+=new EventHandler(page_Init);//添加一個事件 ,//還有就是本來應該添加一個PageBase類的,那樣就可以把真實的路徑信息和查詢參數放進去
    sss = receiveParameters;
    sssobj = obj;
    //receiveParameters.Invoke(temp, obj);
    }
    return temp;
    }
    public System.Reflection.MethodInfo sss { get; set; }
    public object[] sssobj { get; set; }
    protected void page_Init(object sender, EventArgs e)
    {
    sss.Invoke(sender, sssobj);//當page執行到這里時就去調用ReceiveParameters方法 在這里還可以做其它的判斷。。 但不符合編程規范(我的理解)
    }
    ///<summary>
    /// 使工廠可以重用現有的處理程序實例
    ///</summary>
    ///<param name="handler">要重用的 System.Web.IHttpHandler 對象</param>
    public void ReleaseHandler(IHttpHandler handler)
    {
    }
    #endregion
    }
    }
    頁面代碼就是多放幾個方法
    ///<summary>
    /// 一個參數的 如果需要多個則手動添加如public void ReceiveParameters(string name,string value)等等 這樣頁面編譯后就會根據參數自動運行這個方法并轉遞參數值
    ///</summary>
    ///<param name="name">參數名稱為name</param>
    public void ReceiveParameters(string name)
    {
    var temp = Request;
    }

    url的解決了,在來看看干掉試圖的。。
    我只寫了把事件的實體狀態去掉了,然后手動去激發控件的事件,而且就是在url中寫里面解決的 代碼如下:
    代碼如下:

    protected void page_Init(object sender, EventArgs e)
    {
    sss.Invoke(sender, sssobj);
    Page page = (Page)sender;
    foreach (string name in page.Request.Form.AllKeys)//查找form里面所有的字典 其實應該取__EVENTARGUMENT隱藏域的
    {
    try
    {
    System.Web.UI.Control control = page.FindControl(page.Page.Request.Form[name]);//查找這個控件
    if (control != null)
    {
    string value = page.Request.Form[Page.postEventSourceID];
    IPostBackEventHandler ip = control as IPostBackEventHandler;
    if (ip != null)//能轉換成IPostBackEventHandler 那么就激發它
    {
    ip.RaisePostBackEvent(value);
    break;
    }
    IPostBackDataHandler backDataHandler = control as IPostBackDataHandler;
    if (backDataHandler != null)//能轉換成IPostBackDataHandler 就把__EVENTTARGET隱藏域的值傳給控件 然后激發更改事件
    {
    System.Collections.Specialized.NameValueCollection nameValueCollection=new System.Collections.Specialized.NameValueCollection();
    nameValueCollection.Add(page.Request.Form[control.ClientID],page.Request.Form[control.ClientID]);
    backDataHandler.LoadPostData(control.ClientID, nameValueCollection);
    backDataHandler.RaisePostDataChangedEvent();
    }
    }
    break;
    }
    catch
    {
    }
    }
    }

    這樣簡單的處理就完了,
    我希望各位來幫我改進改進,因為我畢竟還不太了解ASp.net的處理機制。。

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    URL重寫及干掉ASP.NET試圖狀態的實現方法

    URL重寫及干掉ASP.NET試圖狀態的實現方法:1、URL重寫已經很普遍了,但基本上大部分的URL重寫都不支持頁面的相對路徑,所有如果想在已經開發好的項目中添加還是有壓力的,第二就是例如微軟的那個URL重寫是根據正則表達式來處理的,那樣是很好,但也有不足之處,就是不方便定位到某個頁面只能有哪些參數
    推薦度:
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 99久久精品国内| 国产精品尹人在线观看| 久久精品中文字幕第23页| 中文字幕av日韩精品一区二区| 欧美黑人巨大精品| 国语自产少妇精品视频蜜桃| 亚洲A∨午夜成人片精品网站| 亚洲第一精品福利| 97精品国产91久久久久久| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 99re热视频这里只精品| 亚洲中文字幕无码久久精品1| 久久免费99精品国产自在现线| 97久人人做人人妻人人玩精品| laowang在线精品视频| 久久99精品久久久久久动态图| 在线观看亚洲精品福利片| 欧美激情视频精品一区二区 | 欧美成人精品高清在线播放| 国产女人18毛片水真多18精品| 四虎国产精品永久地址99| 精品国产福利第一区二区三区| 国产精品视频白浆免费视频| 日韩精品一区二区三区中文| 亚洲欧洲自拍拍偷精品 美利坚| 久久久久亚洲精品无码网址| 国产精品内射视频免费| 97久久精品人人澡人人爽| 亚洲国产综合精品中文第一区| 国产精品欧美久久久天天影视| 国产成人精品无码一区二区| 精品爆乳一区二区三区无码av| 久久夜色精品国产噜噜噜亚洲AV| 九九热精品在线| 1000部精品久久久久久久久| 国产乱码精品一区二区三区中文 | 精品无码人妻一区二区三区 | 99精品久久久久久久婷婷| 99热精品毛片全部国产无缓冲| 99精品国产福利在线观看| 国产三级精品三级在线观看专1|