如何使用 Windows Azure 实现 URL 重写?
Posted
技术标签:
【中文标题】如何使用 Windows Azure 实现 URL 重写?【英文标题】:How to implement URL rewriting with Windows Azure? 【发布时间】:2011-09-17 21:10:25 【问题描述】:我有一个托管在 Windows Azure 上的 ASP.NET / C# 网站。该网站是一个基于预测的社交网站,主页上提供预测摘要。如果您单击摘要,则会使用简单的 QueryString 将您重定向到该预测的详细信息页面。
例如:
http://www.ipredikt.com/details.aspx?id=14
这个特定的预测标题为“帕丽斯·希尔顿将获得诺贝尔和平奖”,所以我想做的是在 上为我的网站实现 URL 重写 >Azure如下:
http://www.ipredikt.com/predictions/14/paris-hilton-will-win-the-nobel-peace-prize
执行此操作有哪些策略和最佳实践?谁能给我指出一两篇关于 Azure 的好文章。
带连字符的标题(“paris-hilton-bla-bla”)实际上只是为了使 URL 更易于阅读;我不认为在加载页面方面完全依赖它。事实上,我可能会允许重复的标题,因为我将依赖 URL 中的预测 ID。
编辑:
忘了提到我们不基于 MVC。我们提出了我们自己的架构,该架构使用 PageMethods 和 WebMethods 将 JSON 返回给客户端。我们依靠 ASP.NET AJAX 来完成所有的 JSON 序列化,并且几乎我们所有的 UI 都是使用 jQuery 在客户端上动态构建的。
编辑:解决方案
既然我已经启动并运行了,我想我会分享我的解决方案。
我创建了一个新课程如下(从某处逐字复制):
public class WebFormRouteHandler<T> : IRouteHandler where T : IHttpHandler, new()
public string VirtualPath get; set;
public WebFormRouteHandler(string virtualPath)
this.VirtualPath = virtualPath;
public IHttpHandler GetHttpHandler(RequestContext requestContext)
return (VirtualPath != null)
? (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(T))
: new T();
我在 Global.asax 中添加了以下方法。实际的方法要长得多(它涵盖了站点中的每个页面)。您会看到我支持以多种不同方式调用预测页面:使用 id、使用 id + 标题等。(页面的“...fb”版本适用于我网站的 Facebook 应用程序版本,使用不同的 MasterPage。)
public static void RegisterRoutes(RouteCollection routes)
// Details : 'predictions' Page
var routeHandlerDetails = new WebFormRouteHandler<Page>("~/details.aspx");
var routeHandlerDetailsFb = new WebFormRouteHandler<Page>("~/detailsfb.aspx");
routes.Add(new Route("predictions/id", routeHandlerDetails));
routes.Add(new Route("predictions/id/title", routeHandlerDetails));
routes.Add(new Route("fb/predictions/id", routeHandlerDetailsFb));
routes.Add(new Route("fb/predictions/id/title", routeHandlerDetailsFb));
...这个方法是从Application_Start()调用的
void Application_Start(object sender, EventArgs e)
RegisterRoutes(RouteTable.Routes);
然后我在 system.webServer 块的 web.config 中添加了以下内容:
<!-- Added for URL Routing -->
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</modules>
<!-- Added for URL Routing -->
<handlers>
<add name="UrlRoutingHandler"
preCondition="integratedMode"
verb="*"
path="UrlRouting.axd"
type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
我还必须从身份验证中排除虚拟“预测”目录(因为我的非身份验证用户几乎可以访问我们网站的所有部分):
<!-- Url routing -->
<location path="predictions">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
最后,我在加载页面时不再依赖 QueryString 字符串参数,所以我不得不编写一些新的辅助方法。这是从新路由 URL 中提取数值的方法(我将对其进行清理,使其只有一个“返回”。):
public static int GetRouteDataValueAsNumber(HttpRequest request, string propertyName)
if ((request == null) ||
(request.RequestContext == null) ||
(request.RequestContext.RouteData == null) ||
(request.RequestContext.RouteData.Values[propertyName] == null))
return -1;
try
return System.Convert.ToInt32(request.RequestContext.RouteData.Values[propertyName]);
catch
return -1;
现在,当我需要读取路由值(如预测 ID)时,我会执行以下操作:
long _predictionId = System.Convert.ToInt64(WebAppUtils.GetRouteDataValueAsNumber(Request, "id"));
效果很好!现在我的网站感觉就像一个 MVC 应用程序,带有友好的自记录 URL。
哦,最后一件事,您还需要启用 HTTP 重定向,如下所示:
开始 => 控制面板 => 程序 => 打开 Windows 功能 => Internet 信息服务 => 万维网服务 => 通用 HTTP 功能 =>(选中复选框)HTTP 重定向。
【问题讨论】:
【参考方案1】:Azure Web 角色安装了 IIS7 网址重写模块 - http://msdn.microsoft.com/en-us/library/dd573358.aspx
此模块的“操作方法”位于http://learn.iis.net/page.aspx/460/using-the-url-rewrite-module/
对于您的巴黎示例,您基本上需要设置一个映射 url 的规则
http://www.ipredikt.com/predictions/14/paris-hilton-will-win-the-nobel-peace-prize
到
http://www.ipredikt.com/details.aspx?id=14
这有点像:
模式 -
^predictions/([0-9]+)/([_0-9a-z-]+)
动作-
details.aspx?id=R:1
有关定义这些规则的更多信息,请参阅http://learn.iis.net/page.aspx/461/creating-rewrite-rules-for-the-url-rewrite-module/
【讨论】:
感谢真实世界的例子。似乎这样做比我想象的要容易。 6 个月前,当我第一次尝试使用 localhost 服务器时,我遇到了一些麻烦,但现在我们在 Azure 上安装了生产和暂存服务器,我敢打赌事情会顺利得多。 如果您的 localhost 服务器有问题,那么不妨试试 IIS Express。并且在使用 Azure 之后,我会接受你的赌注 ;) 不可否认,Azure 不会让这些东西变得“微不足道”,但没有什么比试图强迫localhost:3737 表现得像网络上的东西更糟糕的了。 Azure 的美妙之处在于能够针对暂存服务器执行工作、解决所有问题并按下开关。 Presto-change-o,登台服务器现在是生产服务器。但你的观点是完全正确的。【参考方案2】:实现这一点的最简单方法是使用System.Web.Routing
程序集的编程方法。
这基本上是通过在您的web.config
中包含UrlRoutingModule
并定义基于匹配路由解析目标页面的模式来实现的。如果您熟悉 ASP.NET MVC,那么您之前使用过这种路由策略,但 MVC 并不是必须使用 Routing。
以下是一些可帮助您入门的资源:
MSDN Documentation for the System.Web.Routing namespace - 官方文档
Scott Gu on URL Routing for MVC - * 请注意,本文解释了 ASP.NET MVC 应用程序上下文中的路由,但是,无论您是否使用 MVC,相同的方法都可以使用
ASP.NET Routing... Goodbye URL rewriting, by Chris Cavanagh - 一篇解释性文章
Exploring System.Web.Routing, by Justin Etheredge - 一个案例研究,说明如何独立于 MVC 架构使用路由
关于 Windows Azure ...
如果您采用这种方法,那么您使用的是 Windows Azure 并不重要。但是,我找到了article by Michael Kennedy called ASP.NET Routing in Windows Azure Using WebForms,解释了如何在 Windows Azure 上轻松部署这样的解决方案。文章甚至还有sample project for download。
【讨论】:
感谢您的反馈。真的很感激。我知道如果我们基于 MVC,这会容易得多。但是,我们提出了自己的框架,该框架利用了基于 JSON 的 WebMethods 和 PageMethods 以及通过 jQuery 进行的客户端呈现,因此不依赖于 MVC 的链接将特别有用。 @Armchair Bronco,我发布的所有链接都包含不依赖于 MVC 的代码。我了解您没有使用 MVC。我发布这些文章的原因是因为特定于 MVC 的文章展示了最易读的路由 API 示例。 没错。我记得在我们试图决定架构的早期评估 MVC 时。它让我想起了过去的 ASP 时代,它严重依赖鳄鱼标签 ,我说:“算了吧!想起那些日子让我头疼。”您提供的链接是一个很好的起点,因此请竖起大拇指。一个问题,是否忽略了被认为是“最佳实践”的人类可读的连字符标题?换句话说,我们应该依赖 ID,还是应该实现一些东西来保证每个标题都是唯一的,然后直接使用它? @Armchair Bronco,查看此链接:http://***.com/questions/6397925/does-the-hyphenated-title-matter?。显然有一些成功的网站使用 ID 并忽略了连字符的 slug。但是,由于依赖于整数 ID,记住 URL 肯定会更难,但我怀疑人们会记住有关帕丽斯希尔顿在任何情况下获得诺贝尔和平奖的 URL。无论哪种方式,您都可以在您的应用已经运行后扩展路由分辨率 好点。尽管如果帕丽斯·希尔顿奇迹般地赢得了诺贝尔和平奖,那么所有的赌注都将落空!它将成为互联网上最热门的 URL! :-)以上是关于如何使用 Windows Azure 实现 URL 重写?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Azure 容器中的 blob 中获取所有 URL 的列表?
如何在 Windows Azure 上重写 Codeigniter 的 index.php