Để trang web của bạn tăng thêm khả năng “được tìm thấy” và được trả về các kết quả trên các máy tìm kiếm như google hay yahoo…URL Rewriting sẽ làm điều đó trở nên dễ dàng sẽ làm tăng lên sự tình cờ khi một ai đó tìm kiếm và click vào địa chỉ đó. Ví dụ như địa chỉ weblogs.asp.net/chan thay cho weblogs.asp.net/chan/default.aspx vì vậy sẽ làm tăng thêm khả năng “được tìm thấy”của trang web.
Hướng dẫn 1: Sử dụng tham số Request.PathInfo thay cho QueryStrings
Các bạn hãy nhìn các địa chỉ URL dưới đây:
http://www.store.com/products.aspx/Books
http://www.store.com/products.aspx/DVDs
http://www.store.com/products.aspx/CDs
Hãy để ý, tất cả các địa chỉ trên đều không có Querystring thay vào đó là một giá trị tham số được truyền vào sau Products.aspx. Một công cụ tìm kiếm tự động sẽ hiểu đó là 3 địa chỉ URL khác nhau chứ không phải một địa chỉ với 3 giá trị vào (Công cụ tìm kiếm sẽ bỏ qua phần đuôi file và coi nó như một kí tự trong địa chỉ URL đó)
Để làm điều đó, bạn chỉ cần sử dụng thuộc tính Request.PathInfo sẽ trả về nội dung từng phần của trang theo địa chỉ URL. Do đó với 3 địa chỉ URL ở trên thì Request.PathInfo sẽ trả về “/Books”, "/DVDs", và "/CDs".
Bạn có thể tạo một hàm lấy các danh mục như sau (dùng VB.Net)
Function GetCategory() As String
If (Request.PathInfo.Length = 0) Then
Return ""
Else
Return Request.PathInfo.Substring(1)
End If
End Function
Bạn có thể download file đính kèm bài viết này để được minh họa rõ hơn (UrlRewrite_PathIforApproach)
Hướng dấn 2: Sử dụng một HttpModule để thực hiện URL Rewriting
Một ưu điểm của Request.PathInfo là hàm HttpContext.RewritePath(). Hàm này sẽ giúp lập trình viên có thể rewrite đường dẫn của một địa chỉ URL và ASP.NET tiếp tục xử lý yêu cầu sử dụng đường dẫn mới nhất.
Ví dụ chúng ta có thể sử dụng cả 3 địa chỉ URL sau:
http://www.store.com/products/Books.aspx
http://www.store.com/products/DVDs.aspx
http://www.store.com/products/CDs.aspx
Trông có vẻ như là 3 trang khác nhau của một site (thực sự hấp dẫn với các công cụ tìm kiếm). Sử dụng hàm HttpContext.RewritePath() chúng ta sẽ rewrite được đường dẫn. Khi máy công cụ bắt được trang thay vì nó chỉ gọi đến Products.aspx nó sẽ gọi đến các danh mục như là một Querystring hay một biến PathInfo. Ví dụ:
void Application_BeginRequest(object sender, EventArgs e) {
string fullOrigionalpath = Request.Url.ToString();
if (fullOrigionalpath.Contains("/Products/Books.aspx")) {
Context.RewritePath("/Products.aspx?Category=Books");
}
else if (fullOrigionalpath.Contains("/Products/DVDs.aspx")) {
Context.RewritePath("/Products.aspx?Category=DVDs");
}
}
UrlRewriter.Net module trong ứng dụng Web.confige để có thể ánh xạ những địa chỉ URL trên về một địa chỉ Products.aspx, Cách viết trên thoáng hơn rất nhiều. Bạn có thể download file đính kèm là ví dụ đã được xây dựng để minh họa cho việc sử dụng kĩ thuật UrlRewriter.Net module (file đính kèm cuối bài viết UrlRewrite_HttpModules1.zip)
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="rewriter"
requirePermission="false"
type="Intelligencia.UrlRewriter.Configuration.
RewriterConfigurationSectionHandler,
Intelligencia.UrlRewriter" />
</configSections>
<system.web>
<httpModules>
<add name="UrlRewriter"
type="Intelligencia.UrlRewriter.RewriterHttpModule,
Intelligencia.UrlRewriter"/>
</httpModules>
</system.web>
<rewriter>
<rewrite url="~/products/books.aspx" to="~/products.aspx?category=books" />
<rewrite url="~/products/CDs.aspx" to="~/products.aspx?category=CDs" />
<rewrite url="~/products/DVDs.aspx" to="~/products.aspx?category=DVDs" />
</rewriter>
</configuration>
Đoạn code trên đã cung cấp cả regular expression và kiểm tra địa chỉ URL (Để tránh bạn phải viết nhiều đoạn code trong file web.config. Để tránh việc bạn phải viết những đoạn code cố định, bạn có thể re-write những quy tắc như dưới đây để lấy ra cách danh mục từ địa chỉ URL cho mỗi xâu : "/products/[category].aspx"
<rewriter>
<rewrite url="~/products/(.+).aspx" to="~/products.aspx?category=$1" />
</rewriter>
II. Sử dụng một HttpModule để thực hiện Extension-Less URL Rewriting với IIS7 và Sử dụng ISAPIRewrite để enable Extension-less URL Rewriting cho IIS5 và IIS6
Hướng dẫn 3: Sử dụng một HttpModule để thực hiện Extension-Less URL Rewriting với IIS7.
Ứng dụng HttpModule ở trên vẫn có thể làm việc tốt trong trường hợp khi địa chỉ URL bạn đang re-write có phần đuôi file mở rộng là .aspx, hoặc các loại đuôi file mở rộng khác được cấu hình trong ASP.NET. Khi bạn thi hành không đòi hỏi phải cấu hình server- bạn có thể copy ứng dụng web của mình lên remote server ,nó sẽ chạy tốt.
Nhưng có lúc bạn lại muốn địachỉ URL của bạn được rewrite không có các phần đuôi file mở rộng của ASP.NET (ví dụ .pg, .gif, or .htm) hoặc không có bất cứ một đuôi file mở rộng nào khác. Ví dụ, bạn có thể đưa ra những địa chỉ URL như sau:
http://www.store.com/products/Books
http://www.store.com/products/DVDs
http://www.store.com/products/CDs
Với IIS5 và IIS6, việc xử lý những địa chỉ URL như trên sử dụng ASP.NET không thực sự dễ dàng. Việc thực hiện URL rewriting những địa chỉ URL này trong khuôn khổ ISAPI (Mà nhờ nó ASP.NET mới được thực hiện) không đơn giản. Thay vì bạn cần phải thực hiện,việc rewrite sẽ dễ dàng hơn với yêu cầu sử dụng một ISAPI Filter.
Một điều mới trong IIS7.0 đó là nó có thể dễ dàng xử lý các tình huống này. Bạn có thể sử dụng một HttpModule thi hành ở bất cứ đâu trong khuôn khổ tuyến yêu cầu IIS- có nghĩa là bạn có thể sử dụng URLRewriter module ở trên để truy cập và rewrite extension-less URLs (Hoặc cả những địa chỉ URL với các đuôi file như .asp, .php,.jsp). Đoạn code dưới đây sẽ giải thích tại sao bạn nên cấu hình vói IIS7
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<configSections>
<section name="rewriter"
requirePermission="false"
type="Intelligencia.UrlRewriter.Configuration.
RewriterConfigurationSectionHandler,
Intelligencia.UrlRewriter" />
</configSections>
<system.web>
<httpModules>
<add name="UrlRewriter"
type="Intelligencia.UrlRewriter.RewriterHttpModule,
Intelligencia.UrlRewriter" />
</httpModules>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRewriter"
type="Intelligencia.UrlRewriter.RewriterHttpModule" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<rewriter>
<rewrite url="~/products/(.+)" to="~/products.aspx?category=$1" />
</rewriter>
</configuration>
Chú ý rằng thuộc tính runAllManagedModulesForAllRequests được thiết lập là true trong thẻ <modules> và trong thẻ <system.webServer>. Điều này sẽ chắc chắn rằng UrlRewriter.Net module, được viết trước khi có IIS7, sẽ được gọi và có cơ hội được rewrite tất cả dịa chỉ URL đến server (cả folder). Cái thực sự thuận tiện của file web.config trên là:
Nó sẽ làm việc với mọi thiết bị IIS7.0. Bạn không cần là một administrator để enable bất cứ gì ở remote host.
Vì tôi cấu hình cả UrlRewriter ở cả thẻ <httpModules> và thẻ IIS7 <modules>, nên tôi có thể sử dụng cùng một quy tắc URL Rewriting cho cả 2 được xây dựng trên VS web-server như trong IIS7. Cả 2 đều hỗ trợ extension-less URLRewriting. Điều đó làm cho việc testing và phát triển thực sự dễ dàng.
Bạn có thể download một ứng dụng đơn giản về cách sử dụng kĩ thuật extension-less URL với IIS7 (file đính kèm cuối bài viết UrlRewrite_HttpModules2.zip)
Hướng dẫn 4: Sử dụng ISAPIRewrite để enable Extension-less URL Rewriting cho IIS5 và IIS6
Nếu không muốn đặt mua IIS7.0 cho extension-less URL Rewriting bạn có thể sử dụng một ISAPI Filter để rewrite URL. Có 2 giải pháp cho ISAPI Filter:
Bạn có thể tham khảo cách sử dụng qua đoạn code sau:
[ISAPI_Rewrite]
# fix missing slash on folders
# note, this assumes we have no folders with periods!
RewriteCond Host: (.*)
RewriteRule ([^.?]+[^.?/]) http\://$1$2/ [RP]
# remove index pages from URLs
RewriteRule (.*)/default.htm$ $1/ [I,RP]
RewriteRule (.*)/default.aspx$ $1/ [I,RP]
RewriteRule (.*)/index.htm$ $1/ [I,RP]
RewriteRule (.*)/index.html$ $1/ [I,RP]
# force proper www. prefix on all requests
RewriteCond %HTTP_HOST ^test\.com [I]
RewriteRule ^/(.*) http://www.test.com/$1 [RP]
# only allow whitelisted referers to hotlink images
RewriteCond Referer: (?!http://(?:www\.good\.com|www\.better\.com)).+
RewriteRule .*\.(?:gif|jpg|jpeg|png) /images/block.jpg [I,O]
Chú ý: một điều bất lợi khi sử dụng ISAPI filter là môi trường hosting bị chia sẻ thường không cho phép bạn cài đặt thành phần này, và bạn sẽ cần một hosting server duy nhất ảo hoặc một hosting server duy nhất để sử dụng chúng. Nhưng nếu bạn có một hosting mà cho phép bạn cài đặt ISAPI, thì nó sẽ cho bạn sự mềm dẻo nhất trên IIS5/6 và khắc phục được cho đến khi dùng IIS7.
Xử lý ASP.NET PostBacks với URL Rewrting
Một điều mà mọi người thường mắc phải khi sử dụng ASP.NET và Url-Rewriting đó là việc phải xử lý tình huống postback . Cụ thể là , khi bạn thẻ <form runat="server"> trên trang, ASP.NET sẽ nay lập tức mặc định output thuộc tính action là trang mà nó đang ở. Vấn đề là khi sử dụng URL-Rewriting giá trị <form> control trả lại không đúng như địa chỉ gốc củ yêu cầu (ví dụ : /products/books), nhưng đúng hơn là sẽ được viết lại ở một địa chỉ khác (ví dụ: /products.aspx?category=books). Điều này nghĩa là khi bạn thự hiện postback đến server, địa chỉ URL sẽ không như bạn nghĩ.
Với ASP.NET 1.0 và 1.1, mọi người thường thêm một class vào <form> control và tạo riệng cho nó một cotrol mà trả về action một cách chính xác để sử dụng. Khi nó làm việc, có thể ban đầu sẽ có một chút lộn xộn do đó bạn phải update tất cả các trogn để sử dụng form control, và có thể đôi khi sẽ có vấn đề với giao diện thiết kế trực quan của Visual Studio.
Trong ASP.NET 2.0, có một mẹo mà bạn có thể sử dụng để rewrite thuộc tính "action" trong <form > control. Cụ thể là bạn có thể tận dụng những ưu điểm của cấu trúc mở rộng trong ASP.NET 2.0 Control Adapter để tùy chỉnh sự xê dịch của <form> control, và ghi đè lên giá trị thuộc tính của nó bằng giá trị mà bạn đưa ra. Điều này không đòi hỏi bạn phải thay đổi code trong trang .aspx. Thay vào đó bạn chỉ cần add một file .browser vào folder /app_browsers và thêm một lớp Control Adapter dùng để output thuộc tính mới:
Bạn có thể thấy điều này ở ví dụ 2 vừa down load. Nó làm việc cho cả 2 Request.PathInfo và UrlRewriter.Net module approaches tôi đã sử dụng ở phần hướng dẫn 1 và 2 ở trên, sử dụng thuộc tính Request.RawUrl để lấy địa chỉ gốc, không được rewrite, địa chỉ URL được hoàn trả. Với ISAPIRewrite filter ở hướng dẫn 4 bạn có thể dùng giá trị Request.ServerVariables["HTTP_X_REWRITE_URL"] mà ISAPI filter sử dụng để thay thế cho địa chỉ gốc.
Xử lý CSS và tham chiếu hình ảnh chính xác.
Mọi người thường gặp phải một vấn đề khi sử dụng Url Rewriting lần đầu đó là tìm kiếm tham chiếu hình ảnh và CSS dường như không hoạt động. Điều này là bởi vì chúng có một tham chiếu liên quan đến những file này trong trang HTML- và khi bạn bắt đầu re-write URLs trogn một ứng dụng bạn cần phải hiểu trình duyệt sẽ luôn yêu cầu các files trong hệ cấp bậc logic khác nhau hơn là nó thực sự được lưu trong server.
Ví dụ, khi trang /products.aspx của bạn ở trên có một tham chiếu đến ảnh “logo.jpg” trogn trang .aspx, nhưng được yêu cầu qua địa chỉ /products/books.aspx, khi đó trình duyệt sẽ gửi yêu cầu đến /products/logo.jpg thay vì /logo.jpg khi nó được trả lại trên trang. Để tham chiếu chính xác đến file này, bạn hãy chắc chắn rằng chỉ ra đường dẫn tham chiếu đến CSS và hình ảnh ("/style.css" thay vì of "style.css"). Với ASP.NET controls, bạn cso thể sử dụng cấu trúc ~ để tham chiếu đến các file từ gốc của ứng dụng ví dụ: <asp:image imageurl="~/images/logo.jpg" runat="server"/>
Hi vọng bài viết này giúp các bạn hiểu thêm và sử dụng tốt Rewrite URL