Dot Net Perls

Use OutputStream With XmlWriter - ASP.NET

by Sam Allen

Problem

Effectively use Response.OutputStream along with XmlWriter. We need to write XML directly into an .aspx page in ASP.NET, replacing the entire page with well-formed XML. There are many ways to do this, but some ways are better than others. We want to see how to use XmlWriter and OutputStream to solve our problem easily, and maintain correct content encodings.

Solution: C#

You know what Response.Write does--it is a C# function in ASP.NET that writes text directly to the page. If you call Response.Write in a code-behind file, the parameter will be inserted directly into the page. Let me show some common ASP.NET objects that we can use for our solution.

ObjectUsage of object
Page.ResponseUsed in a code-behind page class as Response
Response.WriteWrite text directly to the page buffer
Response.OutputStreamAllows you to write data to the page output using C# Stream objects
Response.End()Method that stops data from being written

Google Sitemap

For our example, we will make a cool Google sitemap using some of the above methods and objects. Let me say that what we are doing here is replacing the entire .aspx markup stored in the file with the output of code that writes to the Response. It sounds complicated, but it is simpler than some approaches.

What do I put in my .aspx page?

The first code sample here is an example aspx page. I use a script block at the very start of the page to store some C# code. In that block, we need to use the Page_Load event. Don't worry about the parameters to Page_Load or the protected keyword--that is just boilerplate.

<%@ Page Language="C#" %>
<script runat="server" type="text/C#">
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.ContentType = "text/xml"; // Set ContentType.
        // Custom "Google map" function called here.
        WriteGoogleMap("http://dotnetperls.com/", Response.OutputStream);
        Response.End(); // Important!
        return;
    }
</script>

How do we write to the OutputStream?

Let's look at the method that actually writes the XML to the Response.OutputStream. What this method does is construct an entire XML document from start to finish. Because the OutputStream is set as the buffer for XmlWriter, when XmlWriter adds elements they will be added to the Response text automatically.

/// <summary>
/// Write an XML document.
/// </summary>
public void WriteGoogleMap(string urlBase, Stream stream)
{
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Encoding = Encoding.UTF8;
    settings.Indent = true;

    // Write XML to the stream. 'using' will ensure that resources
    // are efficiently managed by the runtime.
    using (XmlWriter writer = XmlWriter.Create(stream, settings))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("urlset",
            "http://www.sitemaps.org/schemas/sitemap/0.9");

        // The following statements and the foreach loop simply add stuff to the XML
        // file. This code isn't important to my example.
        // We use the var keyword for simpler syntax.
        var pageList = from page in _x.Elements("SitePage")
                       where page.Element("Visibility").Value != "External"
                       orderby page.Element("Url").Value
                       select page;

        foreach (XElement page in pageList)
        {
            writer.WriteStartElement("url");
            writer.WriteElementString("loc", urlBase + page.Element("Url").Value);
            writer.WriteEndElement();
        }
        writer.WriteEndElement();
        writer.WriteEndDocument();
    }
}

What should I know about content encoding?

This is important, and is the hardest thing about this stuff. Your text encoding needs to match the XML declaration. Calling Response.Write may result in a different encoding than regular C# strings. So, we can't mix C# XML strings with Response.Write. Don't use Response.Write for XML because it will mess up with your encoding.

Conclusion

Using OutputStream and XmlWriter is a great way to fix encoding problems, and easily create dynamic XML files in aspx code-behind. It works very well and the XML you create will be interoperable and usable in every web browser and compliant program. Response.Write will make your life harder, even though it seems simpler.

Dot Net Perls
About
Sitemap
Source code
RSS
ASP.NET
Page Load Event and AJAX
Custom ASHX Handler Tutorial
Cache Examples and Overview
System.Timers for ASP.NET Website Tutorial
HtmlTextWriter Use
Recent
Pi
NGEN Installer Class
List Element Equality
DateTime Tips and Tricks
Remove HTML Tags From String
© 2008 Sam Allen. All rights reserved.