Routing with Webform

คราวก่อนค้างเอาไว้ว่า ถ้าจะทำ Routing ใน ASP.NET Webform จะทำยังไง มาต่อเลยดีกว่า

เนื่องจาก Routing นั้นเป็นส่วนที่จะเพิ่มเข้ามาใหม่ในตัว Framework ของ ASP.NET 3.5 SP1 นั่นก็หมายความว่าเราสามารถใช้ ASP.NET Routing กับ Web Form ได้เหมือนกับที่เราใช้ความสามารถอื่นๆใน Framework นั่นเอง วิธีที่จะเอามาใช้นั้น Chris Cavanagh ได้ระบุวิธีการไว้ดังนี้

After a little experimentation I found some minimal steps that work pretty well:

  • Create a custom IRouteHandler that instantiates your pages
  • Register new Routes associated with your IRouteHandler
  • That’s it!

ถ้าให้แปลเป็นไทยก็คือ

  • สร้าง class ที่ implement IRouteHandler
  • สร้าง Route ให้ url ที่ต้องการ วิ่งไปที่ IRouteHandler ที่สร้างมาใหม่
  • จบเพียงเท่านี้

สร้าง class ที่ implement IRouteHandler

ใน ASP.NET MVC เราใช้ System.Web.Mvc.MvcRouteHandler เป็นตัว Route Handler เพื่อเรียกใช้ action ให้ตรงกับที่เรา Route ไว้ แต่สำหรับ Webform เราจำเป็นจะต้องทำตัว Route Handler ขึ้นมาเอง

ด้านล่างนี้จะเป็นตัวอย่างง่ายๆของการทำ Route Handler

public interface IRoutablePage
{
    RequestContext RequestContext { set; }
}

public class WebformRouteHandler : IRouteHandler
{
    public WebformRouteHandler(string virtualPath)
    {
        this.VirtualPath = virtualPath;
    }
    public string VirtualPath { get; private set; }
    #region IRouteHandler Members

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        IHttpHandler page = BuildManager.CreateInstanceFromVirtualPath( this.VirtualPath  , typeof(Page)) as IHttpHandler;
        if (page != null)
        {
            IRoutablePage ir = page as IRoutablePage;
            if (ir != null)
                ir.RequestContext = requestContext;
        }
        return page;
    }

    #endregion
}

ตัว interface IRouteHandler นั้นมี method ที่บังคับให้ implement เพียง 1 method คือ GetHttpHandler ซึ่งเราจะใช้ method BuildManager.CreateInstanceFromVirtualPath ช่วยในการสร้าง instance ของ Page หรือหน้าต่างๆขึ้นมา นอกจากนี้เราจะส่ง RequestContext ให้กับหน้านั้นๆหากหน้านั้นทำการ implement IRoutablePage เอาไว้ ซึ่งทำให้เราสามารถเข้าถึง RouteValue ได้ และช่วยให้เราใช้ประโยชน์จาก RouteConstraint ได้ด้วย

สร้าง Route ให้ url ที่ต้องการ วิ่งไปที่ IRouteHandler ที่สร้างมาใหม่

ขั้นตอนนี้จะเป็นการกำหนด Route table ให้กับ web application ของเรา ขั้นแรกให้เพิ่ม Global.asax ขึ้นมาก่อน แล้วใน method Application_Start ให้เพิ่มโค้ดดังนี้

    protected void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes(RouteTable.Routes);
    }


    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.Add("HelloRoute", new Route
        (
           "{name}", new WebformRouteHandler("~/default.aspx")
        ));
    }

แบบนี้หมายความว่า ไม่ว่าอะไรก็ตาม ให้ route เข้า default.aspx ให้หมด

สำหรับ default.aspx ผมเพิ่ม literal control เอาไว้หนึ่งคอนโทรล จะไม่ขอแสดงโค้ด แต่จะใส่ Code Behind เอาไว้ให้

public partial class _Default : System.Web.UI.Page, IRoutablePage
{

    protected void Page_Load(object sender, EventArgs e)
    {
        if (this.requestContext != null)
            Literal1.Text = string.Format("Hello, {0}", this.requestContext.RouteData.Values["name"]);
    }

    #region IRoutablePage Members
    protected RequestContext requestContext;
    RequestContext IRoutablePage.RequestContext{ set { this.requestContext = value; } }
    #endregion
}

ในตอนนี้ถ้าเราลองใช้งาน Routing ดู จะพบว่ายังเจอหน้า 404 อยู่หากเข้าไปที่ ~/{a} เมื่อ {a} เป็น url ใดๆ เพราะ ASP.NET ยังไม่เข้าใจการ Routing เราต้องเพิ่ม Module สำหรับการ Routing ลงไปใน web.config ด้วย

และ

    <httpModules>
        <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </httpModules>

เมื่อทดลองก็จะใช้งานได้

That's it

เอา ASP.NET Routing มาใช้ไม่ใช่เรื่องยาก แต่ว่ายังมีปัญหาอื่นๆตามมาอีกมิใช่น้อยไม่ว่าจะเป็นเรื่อง Security หรือ ASP.NET Ajax เพราะ Web form ไม่ได้ถูกออกแบบมาให้ใช้กับ Routing ตั้งแต่แรกเหมือนพวก framework อื่นๆ

ถ้าให้สรุปก็คือ ถ้าอยากใช้ก็ไม่มีปัญหา ทนใช้ไปก็ได้ ถ้าทนไม่ไหวก็มีสามทางเลือก คือไปใช้ ASP.NET MVC หรือใช้ URL Rewriting เหมือนเดิม และสุดท้ายคือลองใช้ Framework อื่นๆดู

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.