Serving the Correct MIME Type for XHTML using ASP.NET 2.0

Posted on Wed 01 November 2006 in ASP.NET

This example code goes some way to serving XHTML properly, as outlined in the article: Serving the Correct MIME Type for XHTML.

Idealy, text/html should only be served when the user agent specifies acceptance of text/html, but not application/xhtml+xml. However, Internet Explorer 6 does not return anything useful in it's HTTP_ACCEPT response.

Place the following code in the Page_Init section of your master page:

String strContentType = null;

// Determine if the user agent returns any AcceptTypes (HTTP_ACCEPT) response
if (Request.AcceptTypes != null)
{
  // Determine if the user agent can handle XHTML served as "application/xhtml+xml" (e.g. FireFox, Opera)
  if (Array.IndexOf(Request.AcceptTypes, "application/xhtml+xml") > -1)
  {
    strContentType = "application/xhtml+xml";
  }
  else
  {
    // If the user agent does not specifiy acceptence of "application/xhtml+xml", then serve as "text/html" (e.g. Internet Explorer)
    strContentType = "text/html";
  }
}
else
{
  // If AcceptTypes is null, then serve as "application/xhtml+xml" (e.g. W3C Validator)
  strContentType = "application/xhtml+xml";
}

// Set the Response Content Type
Response.ContentType = strContentType.ToString();

if (strContentType == "text/html")
{
  // Generate a "content-type" meta tag in the page head
  HtmlMeta hmtContentType = new HtmlMeta();
  hmtContentType.HttpEquiv = "content-type";
  hmtContentType.Content = strContentType.ToString() + "; charset=UTF-8";
  Page.Header.Controls.Add(hmtContentType);
}
else
{
  // Generate xml declaration
  Response.Write("<?xml version="1.0" encoding="UTF-8" ?>
");
}

// Set the page encoding
Response.ContentEncoding = System.Text.Encoding.UTF8;

// Send a Vary header to inform proxy servers that content negotiation is taking place
Response.AddHeader("Vary", "Accept");

Note

When served as application/xhtml+xml, all <style> and <script> in the XHTML document must be marked as CDATA. Because ASP.NET automatically generates JavaScript, this can be a problem. See Marking ASP.NET 2.0 Generated JavaScript as CDATA for a workaround.