ASP.NET 4的Demo实践:URL路由改进支持

从.NET框架3.5 SP1开始,微软推出了ASP.NET路由支持,从而实现了特定资源的URL与其对应的Web服务器上的物理文件之间的彻底解耦。借助于ASP.NET路由支持,开发人员可以定义一组路由规则,从而实现把路由模式映射到一个生成相应内容的类。例如,你可以把URL“Categories/CategoryName”映射到一个类,该类接收CategoryName而最终生成对应于此种类的产品信息显示于一个网格中的一组HTML标记。有了这样的映射,用户便可以通过访问www.yoursite.com/Categories/Beverages来查看饮料种类对应的所有产品信息。

  在.NET 3.5 SP1中,ASP.NET路由主要是为ASP.NET MVC应用而设计的,虽然在非ASP.NET MVC框架支持的Web窗体应用程序中也有可能实现ASP.NET路由支持。然而,在Web窗体应用程序中实现ASP.NET路由会涉及大量额外的工作。

  在Web窗体中,通常情况下,我们都要把路由模式映射到一个实际的ASP.NET页面。为此,我们需要创建一个路由处理类以便在请求路由URL时调用之,并且在一定意义上实现了把请求调度到适当的ASP.NET页面。例如,为了把一个路由映射到一个物理文件,比如把Categories/CategoryName映射到ShowProductsByCategory.aspx,我们需要如下三个步骤:

  (1)在Global.asax文件中定义映射,用于把路由模式映射到一个路由处理类;

  (2)创建路由处理类,它负责解析网址,把所有路由参数存储到一些目标页面可以访问到的位置(如HttpContext.Items),并返回一个目标页面或处理请求路由的HTTP处理器的实例;

  (3)在目标页面中编写代码来获取路由参数,并使用他们生成页面内容。

  且不说花费了多大的代价仅仅读取前面的语句(更不用担编写之),你完全能够想象到—在Web窗体应用程序中执行ASP.NET路由不一定是开发人员最直接的任务。

  值得庆幸的是,ASP.NET 4.0通过添加一组类和助理方法极大地简化了ASP.NET路由在Web窗体应用程序中的使用。使用ASP.NET 4.0,你会更容易地定义路由规则,而不再需要创建一个自定义路由处理类。本文将详细探讨这方面的改进支持。

  一、ASP.NET路由技术概述

  ASP.NET路由能够干净地实现URL与网页文件名之间的解耦,从而可用于创建干净、简洁且搜索引擎友好的网址。有关为什么应该在Web应用程序中使用ASP.NET路由的详细讨论,在此不作详细讨论,请参考其他有关文章。

  概括地说,ASP.NET路由允许开发人员定义路由规则,从而实现把一个路由模式(如Categories/CategoryName)映射到一个处理请求的类。这些路由规则在应用程序启动时就已经定义在文件Global.asax中的Application_Start事件处理程序中。

  在Web窗体应用程序中,我们可能已经拥有了产生我们感兴趣内容的ASP.NET网页,我们只需要通过路由规则把路由模式映射到这些ASP.NET页面—通过把任何路由参数(例如CategoryName)映射到该ASP.NET页面来实现。当在ASP.NET 3.5 SP1中使用ASP.NET路由时,没有方法直接把路由模式映射到ASP.NET页。相反,我们必须创建一个路由处理类,它负责传递有关传入请求的信息,并且必须返回一个HTTP处理程序来处理此请求。通常,在Web窗体应用程序中一个路由处理类执行以下步骤:

  (1)根据需要解析网址,或许研究某些路由参数,并以这些值为基础作出决定。

  (2)从需要被传递到ASP.NET页面或HTTP处理程序(它们将处理这一请求)的URL加载任何路由参数。总之,我们要确保ASP.NET页面会生成实际内容,因为此请求知道所有路由参数(如CategoryName)的值。一个传达这样的信息的办法是,把它们放在HttpContext.Items集合中—此集合担当存储特定长度的请求信息的数据存储信息库的作用。

  (3)返回执行上述处理的ASP.NET页面或HTTP处理程序的实例。

  通常,这些路由处理程序类具有差不多相似的特征。你把路由参数存储到HttpContext.Items集合中,然后创建并返回一个负责生成该网址对应内容的ASP.NET页面的实例。尽管路由处理类具有相似特征,但是编写这些类是一项冗长的任务,因为每个新路由都需要一个新的处理程序类,而此类需要实现几乎与前一个类同样的任务。

  在ASP.NET 3.5 SP1中使用ASP.NET路由的另一种挑战主要与负责生成最终内容的ASP.NET页面相关。此页面必须从HttpContext.Items集合((或其它其他存储它们的路由处理程序类)中读出路由参数。此外,为一个超链接或Response.Redirect调用生成路由友好的URL(如Categories/CategoryName)的语法也有点冗长和混乱。

  在ASP.NET 4.0中,路由支持得到了增强,包括一些新的路由相关的方法,从而使定义映射到实际ASP.NET页面的路由规则更加简单。在ASP.NET 4.0中,你不再需要创建自定义路由处理程序类作为中介,而只需要从Global.asax文件中的路由规则中直接引用ASP.NET页面即可。当从路由规则中指定一个ASP.NET页面时,路由参数被自动存储在一个新的RouteData集合中,此集合可以从ASP.NET页面中通过Page.RouteData结构进行访问。更重要的是,在.NET框架4.0中包括一个自定义参数控件,这样一来,你可以使用声明的方式从ASP.NET的数据源控件(如SqlDataSource和LinqDataSource等)中使用RouteData中的值,而且也提供了一些方法来生成路由友好的URL,以及重定向到路由友好的网址。

  本文将重点讨论ASP.NET在ASP.NET 4.0中的路由系统改进支持。本文提供的演示程序是一个Web窗体应用程序,这是一个罗斯文商贸网站的前端。它使用了ASP.NET路由支持来创造简洁且搜索引擎友好的网址。例如,/Categories/All将显示所有类别,/Categories/Beverages将列出属于饮料类的所有产品,而/Products/Chai将显示有关产品Chai的细节信息。

  请注意,为了在ASP.NET 3.5 SP1中使用ASP.NET路由支持,你需要明确地在你的项目中添加对System.Web.Routing程序集的引用,并需要添加一些标记到Web.config配置文件中。这些步骤在使用ASP.NET 4.0时不再需要,而且,在Global.asax文件中用于定义路由规则的语法更为短小、简单和具有可读性。

  本文后面的内容将给出在ASP.NET 4.0中使用ASP.NET路由的详细步骤描述。

  二、使用ASP.NET 4.0路由

  下面给出在ASP.NET 4.0中使用ASP.NET路由的详细描述。

  0. 前提

  本文提供的演示程序使用了新添加到ASP.NET 4.0中的ASP.NET路由功能。如果你使用Visual Studio 2010或Visual Web Developer 2010(或更高版本),那么你正好具备了这一前提。

  1.在文件Global.asax中定义路由规则

  要使用ASP.NET路由系统,你需要在应用程序启动时定义一个或多个路由。方法是,在你的项目中添加一个全局应用程序类文件(Global.asax)。在这个文件中,我们将在Application_Start事件中注册这些路由。

  定义于Global.asax文件中的路由指示什么样的路由处理程序负责处理什么样的URL模式。在MVC应用程序中,一种流行的模式是Controller/Action/ID;这意味着针对/Products/View/Aniseed Syrup或Categories/Edit/Beverages的请求将由配置的路由处理程序来处理。在应用程序中定义什么样的路由方面,你可以拥有足够的灵活性。例如,你可以定义模式的多个部分,定义缺少部分的默认值,甚至还要定义针对某些输入类型的限制部分。

  本文演示程序是一个简单的数据驱动应用程序,它使用了Northwind数据库,并接受下列模式的URL:

  /Categories/All—列出数据库中所有产品类型;

  /Categories/CategoryName—列出相应于特定类型的产品信息;

   /Products/ProductName—显示特定产品的信息。

  因此,我在Global.asax文件的Application_Start事件处理程序中定义了三个路由,如以下代码所示。(注:RouteTable对象和RouteCollection类位于System.Web.Routing命名空间。)

    在Application_Start方法中,我们调用了RegisterRoutes,并传递进RouteCollection类型的参数RouteTable.Routes。接下来,在RegisterRoutes方法中,调用RouteCollection类的MapPageRoute方法,它定义了一个路由模式到ASP.NET页面的路由映射。例如,在第一次调用MapPageRoute方法时,我们创建了一个命名为“All Categories”的路由模式—它负责把路由模式Categories/All映射到ASP.NET页面~/ AllCategories.aspx。

  接下来的两个MapPageRoute方法调用使用参数创建路由模式。其中,“View Product”路由把模式Products/{ProductName}映射到ASP.NET页面~/ ViewProduct.aspx。这里,{ProductName}是一个参数,意味着任何Products/ProductName形式的请求都将被路由到~/ViewProduct.aspx页面。不久你就会看到,{ProductName}参数的值可以从页面~/ViewProduct.aspx中通过Page.RouteData参数加以访问。

  2.创建处理请求的ASP.NET页面

  使用ASP.NET 4.0,你不再需要创建一个自定义的路由处理程序类。当你使用MapPageRoute方法时,这一切都会由底层库为你自动完成。剩下的仅仅是,建立处理请求的ASP.NET页面(AllCategories.aspx,CategoryProducts.aspx和ViewProduct.aspx)。当然,本文示例中的这三个网页相当简单—它们都使用数据源控件,并以编程方式绑定到通过路由参数获取的Categories或者Products表格的数据库结果。

void Application_Start(object sender, EventArgs e)

  {

  RegisterRoutes(RouteTable.Routes);

  }

  void RegisterRoutes(RouteCollection routes)

  {

  // Register a route for Categories/All

  routes.MapPageRoute(

  "All Categories", //路由名

  "Categories/All", //路由URL

  "~/AllCategories.aspx" //处理路由的网页

  );

  //处理Categories/{CategoryName}的路由

  //更多信息,请参考http://forums.asp.net/p/1417546/3131024.aspx

  routes.MapPageRoute(

  "View Category", //路由名

  "Categories/{*CategoryName}", //路由URL

  "~/CategoryProducts.aspx" //处理路由的网页

  );

  // Register a route for Products/{ProductName}

  routes.MapPageRoute(

  "View Product", //路由名

  "Products/{ProductName}", //路由URL

  "~/ViewProduct.aspx" //处理路由的网页

  );

  }

  本文演示程序使用LINQ-to-SQL工具实现数据访问。你会在App_Code文件夹下发现一个Northwind.dbml文件,它创建了一个NorthwindDataContext类。ViewProduct.aspx页面中包含一个DetailsView控件,其中的字段用于显示产品的名称,供应商,单位数量,价格以及其他相关信息。页面的代码隐藏类具有以下(省略了部分)代码:

protected void Page_Load(object sender, EventArgs e)

  {

  dvProductInfo.DataSource = new Product[] { Product };

  dvProductInfo.DataBind();

  }

  private Product _Product = null;

  protected Product Product

  {

  get

  {

  if (_Product == null)

  {

  string productName = Page.RouteData.Values["ProductName"] as string;

  NorthwindDataContext DataContext = new NorthwindDataContext();

  _Product = DataContext.Products.Where(p => p.ProductName == productName).SingleOrDefault();

  }

  return _Product;

  }

  }

   在上面的Page_Load事件处理程序中,DetailsView控件被绑定到Product属性返回的Product对象上。在此,Product属性读取Page.RouteData集合中的URL中的ProductName参数值,使用的语法是:Page.RouteData.Values["ProductName"]。然后,在LINQ查询中使用ProductName参数值来取回有关具体产品的信息。

  下面的屏幕截图显示了运行中的ViewProduct.aspx页面。该网页对应的网址是/Products/Chai,有关该Chai的详细信息显示于此页面中。

  在ASP.NET 4.0中设置ASP.NET路由的过程就是这样!但是,在ASP.NET 3.5 SP1中实现上述过程需要五个步骤,而不是二个步骤。

  三、生成路由友好的URL

  在创建超链接或者把用户通过Response.Redirect方法从一个网页导航到另一个页面时,使用定义于Global.asax中的路由模式(而不是使用它的实际名称来引用ASP.NET页面模式)是比较理想的选择。例如,有一个ViewProducts.aspx页面,其中有一个链接—通过此链接可以返回到显示选定产品类别的所有产品信息,而这个产品类别链接到Categories/CategoryName,其中CategoryName是产品类别名,要显示的是此类别产品的信息。此时,你可以使用Page.GetRouteUrl方法生成这些路由友好的URL。这个方法有许多重载版本,但最简单的版本仅接收两个参数:路由名称和参数的值。

  例如,为了取得返回到Categories/CategoryName页面的正确的URL,可以使用以下语法:

Page.GetRouteUrl("View Category", new { CategoryName = CategoryName });

  在这里,“View Category”是定义于文件Global.asax中路由规则的名称,而CategoryName是出现在URL中的CategoryName参数的值。另一个更具体的例子是:

Page.GetRouteUrl("View Category", new { CategoryName = "Beverages" });

另外,Response.Redirect方法还有另一个新的版本,名为Response.RedirectToRoute。像Page.GetRouteUrl方法一样,这个方法能够接收路由名称和参数值,然后将用户重定向到适当的、路由友好的网址。下面的示例演示了如何将用户重定向到一个特定产品的视图:

 Response.RedirectToRoute("View Product", new { ProductName = ProductName });

   四、结论

  ASP.NET路由是.NET框架提供的一个功能强大的库,通过它可以实现URL与底层物理文件间的彻底解耦。自从ASP.NET 3.5 SP1引入后,ASP.NET路由被初步应用于开发ASP.NET MVC应用程序。虽然它也可以用于Web窗体应用程序中,但是配置它需要繁琐的步骤,而且看上去会造成不必要和重复的代码。

  ASP.NET 4.0中加强了ASP.NET路由库,并针对Web窗体应用程序提供了更加灵活的直观的使用场景支持。正如本文中你所看到的,把一个路由模式映射到ASP.NET页面只需要在Global.asax中添加几行代码,而不再需要创建一个自定义的路由处理类。在底层,ASP.NET路由库会自动把路由参数保存到RouteData集合中—然后,你可以从Page类中访问它。而且,这些RouteData值也可以通过像SqlDataSource和ObjectDataSource这样的数据源控件以声明进行访问。

时间: 2024-10-09 19:36:20

ASP.NET 4的Demo实践:URL路由改进支持的相关文章

跟我学ASP.NET MVC之十一:URL路由

跟我学ASP.NET MVC之十一:URL路由摘要: 在MVC框架之前,ASP.NET假定在请求的URLs和服务器硬盘文件之间有直接的关系.服务器的职责是接收浏览器请求,从相应的文件发送输出. 这种方法只能工作于Web表单,每一个ASPX页面既是一个文件,也是一个对应请求的自包含响应.而这对于MVC应用程序来说就无效了,因为请求是由控制器类里的行为方法处理的,而且没有磁盘上一对一关系的文件. ASP.NET平台使用路由系统处理MVC URLs.在这篇文章中,我将向你展示怎样为你的工程使用路由系统

ASP.NET MVC5(一)—— URL路由

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Web.Mvc.Routing.Constraints; 7 using System.Web.Routing; 8 9 namespace UrlAndRoutes 10 { 11 public class RouteConfig 1

ASP.NET MVC 多语言实现——URL路由

考虑实现一个完整的基于asp.net mvc的多语言解决方案,从路由到model再到view最后到数据库设计(先挖好坑,后面看能填多少). 我所见过的多语言做得最好的网站莫过于微软的msdn了,就先从模仿它的路由开始 仅实现相同的url格式很简单,只要将默认的路由加上一个表示语言的变量就可以了 public static void RegisterRoutes(RouteCollection routes) { //other routes routes.MapRoute( name: "Def

ASP.NET MVC 的URL路由介绍

在这个教程中,向你介绍每个ASP.NET MVC一个重要的特点叫做URL路由.URL路由模块是负责映射从浏览器请求到特定的控制器动作. 在教程的第一部分,你将学习标准路由表如何映射到控制器的动作.在教程第二部分,你将学习如何修改默认路由表成为自定义路由. 使用默认路由表 当你创建一个新的ASP.NET MVC 应用程序,应用程序已经配置了默认的URL路由.URL路由在两个地方设置. 第一,URL路由配置在你的应用程序WEB配置文件中(Web.config文件).文件中有四个有关路由的配置 节:s

Asp.Net MVC2.0 Url 路由入门---实例篇

本篇主要讲述Routing组件的作用,以及举几个实例来学习Asp.Net MVC2.0 Url路由技术. 接着上一篇开始讲,我们在Global.asax中注册一条路由后,我们的请求是怎么转到相应的View的呢?Controller和Action是怎么解析的?这就是Routing组件干的事情了. Routing的作用:它首先是获取到View传过来的请求,并解析Url请求中Controller和Action以及数据,其次他将识别出来的数据传递给Controller的Action(Controller

[读书笔记]ASP.NET的URL路由引擎

作用 一般的URL: 举例:http://www.myapp.com/app.aspx?id=2&sessionid=29320xafafa02fa0zga0g8a0z 缺点: 不美观,不清晰 搜索引擎不友好,爬虫无法知道文件名后的更多地产品分类 因此,需要把它映射成更简单易用.涵盖信息更广的URL. 路由映射基础 相关类:RouteCollection 命名空间:System.Web.Routing 方法:RouteCollection.MapPageRoute(),实例方法 基本思路:要使用

【转】ASP.NET MVC 的最佳实践

[这个职位基于创作的本 · 格罗弗 (在 Microsoft 高级开发人员) 的文档. 它是我们打算将此信息集成到 MSDN 上的 MVC 3 文档. 我们希望你的来信和欢迎您可能提出的任何建议.] 本文档提供了一套旨在帮助创建坚实的应用程序的 ASP.NET MVC 开发人员的编码准则. 当然,它是您作为决定,这些准则是适合您的应用程序开发人员. 模型的建议 该模型是用于定义特定于域的对象. 这些定义应包括业务逻辑 (如何对象的行为和涉及). (什么是有效的值为给定的对象) 的验证逻辑. (如

ASP.NET MVC 的最佳实践

[这个职位基于创作的本 · 格罗弗 (在 Microsoft 高级开发人员) 的文档. 它是我们打算将此信息集成到 MSDN 上的 MVC 3 文档. 我们希望你的来信和欢迎您可能提出的任何建议.] 本文档提供了一套旨在帮助创建坚实的应用程序的 ASP.NET MVC 开发人员的编码准则. 当然,它是您作为决定,这些准则是适合您的应用程序开发人员. 模型的建议 该模型是用于定义特定于域的对象. 这些定义应包括业务逻辑 (如何对象的行为和涉及). (什么是有效的值为给定的对象) 的验证逻辑. (如

ASP.NET MVC的运行机制--url的全局分析

全局 首先我们来看一副图片 首先,用户通过Web浏览器向服务器发送一条url请求,这里请求的url不再是xxx.aspx格式,而是http://HostName/ControllerName/ActionName/Parameters的样子.这个请求被ASP.NET MVC的路由映射系统截获.(路由映射可以在Global.asax中配置,我们一会再说)路由映射系统按照映射规则,解析出控制器名ControllerName,Action名ActionName和各个参数Parameters,然后,找寻