擴充方法 之 Redirect 篇

來源:互聯網
上載者:User

前言:

單看標題,可能很多朋友不知道我到底想寫什麼。在寫這篇文章前,我自己跟自己鬥爭了很久,到底該不該寫這篇文章?畢竟從現實主義來看,這篇文章可能落入“瞎扯淡”的行列,因為對大多數朋友來說,以下的所有擴充方法可能都不會用到。

如果真是這樣,就當作一個“漫無邊際”的想法來看好了。如果你根本不想浪費你的寶貴時間,就點這裡 Redirect 回部落格園首頁,呵呵

 

一個 Redirect 為什麼也可以耗費一篇文章的筆墨?

就 Redirect 一詞成文的先例估計不會是我,但如果 擴充方法 + Redirect 這個話題,我可能就是第一人了 。

 

葫蘆裡賣的是什麼藥?

這個“漫無邊際”的想法實現的效果是:

如果頁面是Foo.aspx,

    • 通過 this.View<Foo>() 來Redirect;
    • 通過 this.Url<Foo>() 來擷取Url;
    • 通過 this.Url<Foo>( new {param1= "value1", param2= "value2"}); 來返回帶參數的Url。

 

“漫無邊際”的想法來源:

Asp.Net MVC 是這個想法的主要來源,學習過 Asp.Net MVC的朋友都熟悉Controller 是如何獲知返回的頁面,主要方法:

public ActionResult Index(){    return View();    return View("ViewName");    return View("ViewName", new { ReturnUrl ="Foo"});    return RedirectToAction("ActionName");}

 

不懂 Asp.Net MVC 的朋友也沒關係,因為本文實際上跟 Asp.Net MVC 完全沒關係,跟稍後講 WebForm 的 View 擴充方法也完全是沒有任何一點關係,僅是方法名相同而已。

 

如何??

對於最簡單的情況:頁面在根目錄,就直接根據 類名 + ".aspx" 返回就可以了

public static string Url<T>(this IHttpHandler httpHandler ){    return string.Format("~/{0}.aspx", typeof(T).Name);}

 

但如果是多層目錄:

如何根據類型來返回我們需要的頁面 Url 呢?那麼我們得變通一下才行。怎麼變通?就是把命名空間也扯上來:

例如這裡Home檔案夾裡的Index.aspx 頁面背景命名空間是 RedirectTests.Views.Home,就根據這個命名空間和類名來拼裝出 "~/Views/Home/Index.aspx" 還不簡單嘛。

範例程式碼:

public static string Url<TView>(this IHttpHandler httpHandler){    string fullViewName = typeof(TView).FullName;    string[] splits = fullViewName.Split('.');    if (splits.Length < 2)        throw new ArgumentException("Cannot find the namespace on view name");    return string.Format("~/Views/{0}/{1}.aspx", splits[splits.Length - 2], splits[splits.Length - 1]);}

 

以上代碼限制路徑只能在 Views 檔案夾下了,有興趣的朋友不妨改改。

 

如何為 Url 添加查詢字串?

啥?這也是一個問題?我見過不少朋友寫查詢字串時基本上是這樣寫的:

string url = "~/Foo.aspx?param1=" + value1 + "&param2=" + value2 ...;
 

或者,想寫美觀一點的朋友就這樣寫:

string url = string.Format( "~/Foo.aspx?param1={0}&param2={1}" , value1, value2);

 

當查詢字串比較長時,那可就有些亂了。個人覺得以Asp.Net MVC 那種形式來書寫很不錯,這就產生另一個“漫無邊際”的想法,請看下面的寫法:

this.Url<Foo>(new { param1 = "value1", param2 = "value2" }); 

當然,執行效率肯定稍遜一籌啦,因為用了反射(題外話,其實大家可以不必聞“射”喪膽,老趙的關於快速反射的開源項目很好很強大)。

 

public static string Url<TView>(this IHttpHandler httpHandler, object param){    string queryString = param.ToQueryString();    string virtualPath = string.Format("{0}?{1}", httpHandler.Url<TView>(), queryString);    return virtualPath;}

 
/// <summary>/// 拼裝查詢字串/// </summary>/// <typeparam name="T"></typeparam>/// <param name="model"></param>/// <returns></returns>public static string ToQueryString<T>(this T model){    StringBuilder sb = new StringBuilder();    if (model != null)    {        Type type = model.GetType();        //遍曆所有屬性,拼裝查詢字串        type.GetProperties().ForEach(p =>        {            sb.Append(p.Name);            sb.Append("=");            sb.Append(UrlEncode(p.GetValue(model, null)));            sb.Append("&");        });        if (sb.Length > 0)        {            //去掉最後一個“&”             return sb.ToString(0, sb.Length - 1);        }    }    return sb.ToString();}/// <summary>/// Url編碼/// </summary>/// <param name="obj"></param>/// <returns></returns>public static string UrlEncode(object obj){    if (obj == null)    {        return string.Empty;    }    else if (obj is DateTime)    {        string value = ((DateTime)obj).ToString("yyyy-MM-dd HH:mm:ss.ffffff");        return System.Web.HttpUtility.UrlEncode(value);    }    return System.Web.HttpUtility.UrlEncode(obj.ToString());}

 

以上代碼關於 Url 編碼的部分,你可以看到如果是DateTime類型轉字串時,這裡進行特定格式的轉化。因為如果不這樣轉化,當擷取這個DateTime類型時,不能保證能從字串轉回正確的DateTime。

那麼,有了上面介紹,自然而然一堆擴充方法就呼之欲出了:

 

public static void View<TView>(this IHttpHandler httpHandler){    HttpContext.Current.Response.Redirect(httpHandler.Url<TView>());}public static void View<TView>(this IHttpHandler httpHandler, object param){    HttpContext.Current.Response.Redirect(httpHandler.Url<TView>(param));}public static void ViewHome(this IHttpHandler httpHandler){    HttpContext.Current.Response.Redirect("~");}public static void ViewLogin(this IHttpHandler httpHandler){    ViewLogin(httpHandler,null);}public static void ViewLogin(this IHttpHandler httpHandler, string returnUrl){    string virtualPath = FormsAuthentication.LoginUrl;    if (!string.IsNullOrEmpty(returnUrl))        virtualPath += "?ReturnUrl=" + returnUrl;    HttpContext.Current.Response.Redirect(virtualPath);}

 

結束?

當然沒結束。以上的 Url 返回的只能是.aspx的頁面,那麼IHttpHandler 的情況呢?

string handlerUrl = this.Url<Handler1>();
最終也可以實現以上效果,但是Url 方法就要適當改改了,這裡我就不再貼代碼了。

 

總結:

最後還是要說的是,這是一個“漫無邊際”的想法。

如果想看其他不那麼“漫無邊際”的文章,下面有另外幾篇 :

擴充方法 之 基本資料篇

擴充方法 之 Asp.Net篇

擴充方法、介面和繼承帶來的有趣現象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.