пятница, 11 июля 2008 г.

URL Rewrite - .NET

Столкнулся с необходимостью сделать ЧПУ (человеко-понятные урл`ы) на .NET`е.
Первым под руку попался компонент urlrewriting.net. Всё было ок, пока не выяснилось, что PostBack`и не работают - не передается информация и IsPostBack=false. Поковырялся... и нашел другой компонент - urlrewriter.net - он работал сразу, только вот ссылку в поле формы action не ту писал (а точнее вообще не писал, но хоть работало). Долго копал интернет - оказалось есть "чистый" способ.

Оговорюсь - сайт на C# ASP.NET 2.0.

Делаем в корне сайта папку App_Browsers. Создаем файл Form.browser с содержимым:

<browsers>

<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="FormRewriterControlAdapter" />
</controlAdapters>
</browser>

</browsers>


далее в папке App_Code создаем файл FormRewriter.cs с содержимым:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

///
/// Summary description for FormRewriter
///

public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
base.Render(new RewriteFormHtmlTextWriter(writer));
}
}
public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
public RewriteFormHtmlTextWriter(HtmlTextWriter writer) : base(writer)
{
this.InnerWriter = writer.InnerWriter;
}
public override void WriteAttribute(string name, string value, bool fEncode)
{
if (name == "action")
{
HttpContext Context;
Context = HttpContext.Current;
if (Context.Items["ActionAlreadyWritten"] == null)
{
value = Context.Request.RawUrl;
Context.Items["ActionAlreadyWritten"] = true;
}
}
base.WriteAttribute(name, value, fEncode);
}
}



Пояснение простое:
1 - это обработчик для разных браузеров
2 - это код, который подменяет тег action у формы.

И PostBack теперь правильно работает...

3 комментария:

zg комментирует...

В последнем Intelligencia.UrlRewriter есть FormRewriterControlAdapter, который реализует подобный функционал, хотя конечно и самому написать несложно.

Анонимный комментирует...

День добрый.
Всем хорош (по крайней мере PostBack ожил), но:
1. Где взять путнее опиание?
2. Что он вытворяет при Login/Logout через System.Web.UI.WebControls.Login?
Нужно просто остаться на той же странице ~/start.
т.е.
(forms name=".ASPXFORMSAUTH" defaultUrl="~/start" loginUrl="~/start" /)
но
"~/start" = "~/User/Default.aspx"

Константин комментирует...

спасибо за полезное решение