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.


Marking ASP.NET 2.0 Generated JavaScript as CDATA

Posted on Wed 01 November 2006 in ASP.NET

The following code example is a workaround for marking ASP.NET generated JavaScript as CDATA, which is required when serving XHTML ASP.NET 2.0 pages as application/xhtml+xml (see Serving the Correct MIME Type for XHTML using ASP.NET 2.0).

Place the following code in your master page:

protected override void Render(HtmlTextWriter writer)
{
  StringWriter stwHtml = new StringWriter();
  base.Render(new HtmlTextWriter(stwHtml));
  String strHtml = stwHtml.ToString();

  // Enclose ASP.NET generated client ECMAScript / JavaScript in CDATA Wrapper
  Regex regScriptCDATA = new Regex("(<script\stype="text\/....script">(?:\s)*?)" + "(?:<!--\s)" + "((?:.|
)*?)" + "(?:// -->)" + "((?:\s)*?<\/script>)");
  String strScriptCDATA = "$1" + "<!--//--><![CDATA[//><!--
" + "$2" + "
//--><!]]>" + "$3";

  strHtml = regScriptCDATA.Replace(strHtml, strScriptCDATA);


  writer.Write(strHtml);
}

You may need to add the following at the beginning of your master page code:

using System.IO;
using System.Text.RegularExpressions;