<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codelab Blog &#187; XHTML</title>
	<atom:link href="http://blog.codelab.co.nz/tag/xhtml/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.codelab.co.nz</link>
	<description>Technical Articles and News from Codelab Ltd</description>
	<lastBuildDate>Tue, 17 Jan 2012 13:10:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>W3C Validation and ASP.NET ViewState</title>
		<link>http://blog.codelab.co.nz/2008/11/25/w3c-validation-and-aspnet-viewstate/</link>
		<comments>http://blog.codelab.co.nz/2008/11/25/w3c-validation-and-aspnet-viewstate/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 10:02:31 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[ViewState]]></category>
		<category><![CDATA[W3C]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://blog.codelab.co.nz/?p=47</guid>
		<description><![CDATA[The problem I came across a very interesting point about validating XHTML pages using W3C XHTML Strict and ViewState.   By default ASP.NET ViewState adds a number of hidden fields to handle the postback of ASP.NET pages, control state and control event validation.  See example below. &#60;input type=&#8221;hidden&#8221; name=&#8221;__VIEWSTATE&#8221; id=&#8221;__VIEWSTATE&#8221; value=&#8221;"  /&#62; When validating web pages [...]]]></description>
			<content:encoded><![CDATA[<p><strong>The problem</strong></p>
<p>I came across a very interesting point about validating XHTML pages using W3C XHTML Strict and ViewState.   By default ASP.NET ViewState adds a number of hidden fields to handle the postback of ASP.NET pages, control state and control event validation.  See example below.</p>
<blockquote><p>&lt;input type=&#8221;hidden&#8221; name=&#8221;__VIEWSTATE&#8221; id=&#8221;__VIEWSTATE&#8221; value=&#8221;"  /&gt;</p></blockquote>
<p>When validating web pages using the XHTML strict option, you will find that the above line is invalid:</p>
<blockquote><p>value of attribute &#8220;ID&#8221; invalid: &#8220;_&#8221; cannot start a name .<br />
…type=&#8221;hidden&#8221; name=&#8221;__VIEWSTATE&#8221; id=&#8221;__VIEWSTATE&#8221; value=&#8221;/wEPDwUJOTkzNjk4NjQ4</p></blockquote>
<p>This becomes a major issue when you have clients who expect their product to be compliant with todays web standards.</p>
<p><strong>The solution</strong></p>
<p><em>Step 1 -</em> I created a FilterModule that inherits the IHttpModule interface which will be the basis of renaming the __VIEWSTATE to VIEWSTATE.</p>
<blockquote><p>using System;<br />
using System.Web;</p>
<p>namespace Company.Utilities<br />
{<br />
public class IdFilterModule : IHttpModule<br />
{<br />
public void Dispose()<br />
{<br />
}<br />
public void Init(HttpApplication app)<br />
{<br />
app.ReleaseRequestState += new EventHandler(InstallResponseFilter);<br />
}<br />
private void InstallResponseFilter(object sender, EventArgs e)<br />
{<br />
HttpResponse response = HttpContext.Current.Response;</p>
<p>if (response.ContentType == &#8220;text/html&#8221;)<br />
{<br />
response.Filter = new IdFilter(response.Filter);<br />
}<br />
}<br />
}<br />
}</p></blockquote>
<p>The above code creates a event handler called InstallResponseFilter that gets fired when the ReleaseRequestState event is raised.   The ReleaseRequestState event saves all the current state data.</p>
<p><em>Step 2 -</em> I then create a class inheriting from the Stream class that takes the current state data and does a simple search and replace on the key ViewState identifiers and adjusts the output to be what we decide is valid XHTML.</p>
<blockquote><p>public class IdFilter : Stream<br />
{<br />
Stream responseStream;<br />
StringBuilder responseHtml;<br />
long position;</p>
<p>public IdFilter(Stream inputStream)<br />
{<br />
responseStream = inputStream;<br />
responseHtml = new StringBuilder();<br />
}</p>
<p>public override bool CanRead<br />
{<br />
get<br />
{<br />
return true;<br />
}<br />
}<br />
public override bool CanSeek<br />
{<br />
get<br />
{<br />
return true;<br />
}<br />
}<br />
public override bool CanWrite<br />
{<br />
get<br />
{<br />
return true;<br />
}<br />
}<br />
public override void Close()<br />
{<br />
responseStream.Close();<br />
}<br />
public override void Flush()<br />
{<br />
responseStream.Flush();<br />
}<br />
public override long Length<br />
{<br />
get<br />
{<br />
return 0;<br />
}<br />
}<br />
public override long Position<br />
{<br />
get<br />
{<br />
return position;<br />
}<br />
set<br />
{<br />
position = value;<br />
}<br />
}<br />
public override long Seek(long offset, SeekOrigin origin)<br />
{<br />
return responseStream.Seek(offset, origin);<br />
}<br />
public override void SetLength(long length)<br />
{<br />
responseStream.SetLength(length);<br />
}<br />
public override int Read(byte[] buffer, int offset, int count)<br />
{<br />
return responseStream.Read(buffer, offset, count);<br />
}<br />
public override void Write(byte[] buffer, int offset, int count)<br />
{<br />
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);</p>
<p>Regex eof = new Regex(&#8220;&lt;/html&gt;&#8221;, RegexOptions.IgnoreCase);</p>
<p>if (!eof.IsMatch(strBuffer))<br />
{<br />
responseHtml.Append(strBuffer);<br />
}<br />
else<br />
{<br />
responseHtml.Append(strBuffer);</p>
<p>string finalHtml = responseHtml.ToString();</p>
<p>finalHtml = finalHtml.Replace(&#8220;id=\&#8221;__VIEWSTATE\&#8221;", &#8220;id=\&#8221;VIEWSTATE\&#8221;");<br />
finalHtml = finalHtml.Replace(&#8220;id=\&#8221;__EVENTARGUMENT\&#8221;", &#8220;id=\&#8221;\&#8221;EVENTARGUMENT&#8221;);<br />
finalHtml = finalHtml.Replace(&#8220;id=\&#8221;\&#8221;__EVENTTARGET&#8221;, &#8220;id=\&#8221;\&#8221;EVENTTARGET&#8221;);<br />
finalHtml = finalHtml.Replace(&#8220;  /&gt;&#8221;, &#8220;&gt;&#8221;);<br />
finalHtml = finalHtml.Replace(&#8221; /&gt;&#8221;, &#8220;&gt;&#8221;);<br />
finalHtml = finalHtml.Replace(&#8220;/&gt;&#8221;, &#8220;&gt;&#8221;);</p>
<p>byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);</p>
<p>responseStream.Write(data, 0, data.Length);<br />
}<br />
}<br />
}</p></blockquote>
<p>The new IdFilterModule gets registered is the web.config file under httpModules.</p>
<p>References:</p>
<p><a href="http://forum.umbraco.org/yaf_postst5965_W3C-Validation-ASPNET-ViewState-and-HTML-401.aspx">http://forum.umbraco.org/yaf_postst5965_W3C-Validation-ASPNET-ViewState-and-HTML-401.aspx</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.web.httpapplication.releaserequeststate.aspx">http://msdn.microsoft.com/en-us/library/system.web.httpapplication.releaserequeststate.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codelab.co.nz/2008/11/25/w3c-validation-and-aspnet-viewstate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

