博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
艾伟_转载:扩展方法 之 Redirect 篇
阅读量:6760 次
发布时间:2019-06-26

本文共 4172 字,大约阅读时间需要 13 分钟。

前言:

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

  如果真是这样,就当作一个“漫无边际”的想法来看好了。如果你根本不想浪费你的宝贵时间,就点 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); }

  但如果是多层目录:

image

  如何根据类型来返回我们需要的页面 Url 呢?那么我们得变通一下才行。怎么变通?就是把命名空间也扯上来:

image

  例如这里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
(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 的情况呢?

image

string handlerUrl = this.Url
(); 最终也可以实现以上效果,但是Url 方法就要适当改改了,这里我就不再贴代码了。

总结:

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

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

转载地址:http://fubeo.baihongyu.com/

你可能感兴趣的文章
Redis
查看>>
XINS 3.0 正式版发布,远程 API 调用规范
查看>>
sqlserver 2005 64bit express
查看>>
(转)Oracle中For和while及一些应用
查看>>
jQuery基础及选择器
查看>>
DragonFly BSD 3.2 发布
查看>>
Mozilla 发布 Popcorn Maker,在线创作视频
查看>>
C#中为什么需要装箱拆箱操作?
查看>>
PHP类中一般方法与静态方法的疑问
查看>>
[转]PHP花括号变量
查看>>
【Opencv学习】摄像头采集、录像、截图小工具
查看>>
Fedora16安装中文语言包和中文输入法
查看>>
Windows 8实用窍门系列:14.windows 8中粘贴板(剪切板)的使用
查看>>
长连接API小心“窜包”问题
查看>>
开发者基础知识游戏,共10关,欢迎挑战
查看>>
ASP.NET中 RadioButtonList(单选按钮组)的使用
查看>>
SESSION 丢失
查看>>
DES可逆加解密
查看>>
图解Undo原理
查看>>
Kinect for Windows SDK V1.7 发布
查看>>