艾伟_转载:扩展方法 之 Redirect 篇

前言:

  单看标题,可能很多朋友不知道我到底想写什么。在写这篇文章前,我自己跟自己斗争了很久,到底该不该写这篇文章?毕竟从现实主义来看,这篇文章可能落入“瞎扯淡”的行列,因为对大多数朋友来说,以下的所有扩展方法可能都不会用到。

  如果真是这样,就当作一个“漫无边际”的想法来看好了。如果你根本不想浪费你的宝贵时间,就点这里 Redirect 回博客园主页,呵呵

一个 Redirect 为什么也可以耗费一篇文章的笔墨?

  就 Redirect 一词成文的先例估计不会是我,但如果 扩展方法 + Redirect 这个话题,我可能就是第一人了。

葫芦里卖的是什么药?

  这个“漫无边际”的想法实现的效果是:

  如果页面是Foo.aspx,

  • 通过 this.Url() 来获取Url;
  • 通过 this.View() 来Redirect;
  • 通过 this.Url( 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(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(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(this IHttpHandler httpHandler, object param){string queryString = param.ToQueryString();string virtualPath = string.Format("{0}?{1}", httpHandler.Url(), queryString);return virtualPath;}

 

/// 拼装查询字符串public static string ToQueryString(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();}/// Url编码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(this IHttpHandler httpHandler){    HttpContext.Current.Response.Redirect(httpHandler.Url());}public static void View(this IHttpHandler httpHandler, object param){    HttpContext.Current.Response.Redirect(httpHandler.Url(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 方法就要适当改改了,这里我就不再贴代码了。

总结:

  最后还是要说的是,这是一个“漫无边际”的想法。

  如果想看其他不那么“漫无边际”的文章,下面有另外几篇

时间: 2024-10-22 09:59:04

艾伟_转载:扩展方法 之 Redirect 篇的相关文章

扩展方法 之 Redirect 篇

前言: 单看标题,可能很多朋友不知道我到底想写什么.在写这篇文章前,我自己跟自己斗争了很久,到底该不该写这篇文章?毕竟从现实主义来看,这篇文章可能落入"瞎扯淡"的行列,因为对大多数朋友来说,以下的所有扩展方法可能都不会用到. 如果真是这样,就当作一个"漫无边际"的想法来看好了.如果你根本不想浪费你的宝贵时间,就点这里 Redirect 回博客园主页,呵呵 一个 Redirect 为什么也可以耗费一篇文章的笔墨? 就 Redirect 一词成文的先例估计不会是我,但如

艾伟_转载:扩展方法 之 基本数据篇

前一篇我列举了几个最常用到的基于Asp.Net的扩展方法,而这一篇基于基本数据的扩展方法理应不会逊一筹,因为它不局限于Asp.Net.何谓基本数据,这里直接摆定义: C# 中有两种基本数据类型:值类型和引用类型. 值类型包括:简单类型.结构类型.枚举类型:引用类型包括:Object 类型.类类型.接口.代表元.字符串类型.数组. 说白了这篇就是扩展 int, string, double, DateTime...等基本类型.这么多数据类型,如果int来个扩展,double也来个扩展,肯定会是一个

艾伟_转载:自用扩展方法分享

引言 自从用上扩展方法以来,就欲罢不能了,它们大大提升了我的代码编写效率,现在我已对其产生了高度依赖.在此分享一下自己的常用扩展方法集,方便大家使用. (其中有些是借鉴或挪用自其它博友的文章,在此尤其感谢鹤冲天的诸多分享) 源代码在文章末尾处提供. 示例 public static string ExpandAndToString(this System.Collections.IEnumerable s, string 间隔字符) 功能:将集合展开并分别执行ToString方法,再以指定的分隔

艾伟_转载:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现

在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高级语言更多的CLR细节.因此,如果您想要通过学习IL来了解CLR,那么这个过程很可能会"事倍功半".因此,从这个角度来说,老赵并不倾向于学习IL.不过严格说来,即使IL无法看出CLR的细节,也不足以说明"IL无用"--这里说"无用"自然有些夸张.但是

扩展方法 之 基本数据篇

前一篇我列举了几个最常用到的基于Asp.Net的扩展方法,而这一篇基于基本数据的扩展方法理应不会逊一筹,因为它不局限于Asp.Net.何谓基本数据,这里直接摆定义: C# 中有两种基本数据类型:值类型和引用类型. 值类型包括:简单类型.结构类型.枚举类型:引用类型包括:Object 类型.类类型.接口.代表元.字符串类型.数组. 说白了这篇就是扩展 int, string, double, DateTime...等基本类型.这么多数据类型,如果int来个扩展,double也来个扩展,肯定会是一个

艾伟_转载:打造优雅的Linq To SQL动态查询

首先我们来看看日常比较典型的一种查询Form 这个场景很简单:就是根据客户名.订单日期.负责人来作筛选条件,然后找出符合要求的订单. 在那遥远的时代,可能避免不了要写这样的简单接口: public interface IOrderService{ IList<Order> Search(string customer, DateTime dateFrom, DateTime dateTo, int employeeID);} 具体爱怎么实现就怎么实现啦,存储过程,ORM框架.这里假定是用了孩童

艾伟_转载:[一步一步MVC]第五回:让TagBuilder丰富你的HtmlHelper

本系列文章导航 [一步一步MVC]第一回:使用ActionSelector控制Action的选择 [一步一步MVC]第二回:还是ActionFilter,实现对业务逻辑的统一Authorize处理 [一步一步MVC]第三回:MVC范例大观园 [一步一步MVC]第四回:漫谈ActionLink,有时"胡搅蛮缠" [一步一步MVC]第五回:让TagBuilder丰富你的HtmlHelper [一步一步MVC]第六回:什么是MVC(上)? 对HtmlHelper进行扩展,是MVC中对于Vie

艾伟_转载:数据库设计与Linq增强使用

最近对数据库的设计有些想法,貌似一般数据都有些通用字段     public interface IData     {         ///          /// 数据ID标识         ///         decimal ID { get; set; }         ///          /// 更新时间         ///         DateTime UpdateTime { get; set; }         ///          /// 数据状

艾伟_转载:[一步一步MVC]第四回:漫谈ActionLink,有时“胡搅蛮缠”

本系列文章导航 [一步一步MVC]第一回:使用ActionSelector控制Action的选择 [一步一步MVC]第二回:还是ActionFilter,实现对业务逻辑的统一Authorize处理 [一步一步MVC]第三回:MVC范例大观园 [一步一步MVC]第四回:漫谈ActionLink,有时"胡搅蛮缠" [一步一步MVC]第五回:让TagBuilder丰富你的HtmlHelper [一步一步MVC]第六回:什么是MVC(上)? MVC时代来临了,但是一开始是不被很多人接受的.可能