Aug

29

Returning XML from a WebForm page

Written by Michael Mattax

I often want to create a web service that returns XML (e.g. creating a RSS feed or when you want to use HTTPService in Flex). This is a trivial problem in a web framework that is close to the HTTP model, simply alter the content-type header and output your XML. Doing this in a WebForms model can be a bit tricky and buggy. To alleviate this pain, I wrote a little wrapper that “fixes” the WebForms model in these situations. Here is how it works:

I have an abstract class, NServlet, that extends System.Web.UI.Page:

using System;
using System.Collections.Specialized;

public abstract class NServlet : System.Web.UI.Page
{
    public NServlet()
    {

    }
    protected void Page_Load(object sender, EventArgs e)
    {

        Response.ClearHeaders();
        Response.ClearContent();
        string response = null;
        switch (Request.HttpMethod)
        {
            case "POST":
                response = doPost(Request.Form);
                break;
            case "GET":
                response = doGet(Request.QueryString);
                break;
            default:
                throw new Exception(Request.HttpMethod + "not supported.");

        }
        Response.ContentType = "text/xml";
        Response.Write(response);
        Response.Flush();
        Response.Close();
    }
    public abstract string doGet(NameValueCollection querystring);
    public abstract string doPost(NameValueCollection postadata);

}

The main idea here is to clear out any HTTP Headers and Content that .NET thinks we want and then call an abstract method that seemingly will generate our XML response. We then tell the server to treat our document as xml and write the response to the client. Take particular notice of the order I do these in, if not done properly you will get a mix of HTML and XML.

Now were ready to create a new WebForm. First delete out all the HTML in the .aspx file, so that it is just a one-liner:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TopLevelServices.aspx.cs" Inherits="TopLevelServices" %>

In the code behind we will have our partial class extend NServlet instead of the System.Web.UI.Page, of course we will be required to implement doGet and doPost:

using System.Collections.Specialized;
public partial class TopLevelServices : NServlet
{
    public override string doGet(NameValueCollection querystring)
    {
       return doPost(querystring);
    }
    public override string doPost(NameValueCollection postdata)
    {
        return "<foo>bar</foo>";
    }
}

And where done! If your at all familiar with J2EE your probably smiling right now; this is how I am returning XML from WebForm pages. It is clean and certainly reusable. Until next time, happy hacking.

Leave a Reply