W3C Validation and ASP.NET ViewState

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.

<input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=””  />

When validating web pages using the XHTML strict option, you will find that the above line is invalid:

value of attribute “ID” invalid: “_” cannot start a name .
…type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=”/wEPDwUJOTkzNjk4NjQ4

This becomes a major issue when you have clients who expect their product to be compliant with todays web standards.

The solution

Step 1 - I created a FilterModule that inherits the IHttpModule interface which will be the basis of renaming the __VIEWSTATE to VIEWSTATE.

using System;
using System.Web;

namespace Company.Utilities
{
public class IdFilterModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication app)
{
app.ReleaseRequestState += new EventHandler(InstallResponseFilter);
}
private void InstallResponseFilter(object sender, EventArgs e)
{
HttpResponse response = HttpContext.Current.Response;

if (response.ContentType == “text/html”)
{
response.Filter = new IdFilter(response.Filter);
}
}
}
}

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.

Step 2 - 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.

public class IdFilter : Stream
{
Stream responseStream;
StringBuilder responseHtml;
long position;

public IdFilter(Stream inputStream)
{
responseStream = inputStream;
responseHtml = new StringBuilder();
}

public override bool CanRead
{
get
{
return true;
}
}
public override bool CanSeek
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return true;
}
}
public override void Close()
{
responseStream.Close();
}
public override void Flush()
{
responseStream.Flush();
}
public override long Length
{
get
{
return 0;
}
}
public override long Position
{
get
{
return position;
}
set
{
position = value;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
return responseStream.Seek(offset, origin);
}
public override void SetLength(long length)
{
responseStream.SetLength(length);
}
public override int Read(byte[] buffer, int offset, int count)
{
return responseStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

Regex eof = new Regex(“</html>”, RegexOptions.IgnoreCase);

if (!eof.IsMatch(strBuffer))
{
responseHtml.Append(strBuffer);
}
else
{
responseHtml.Append(strBuffer);

string finalHtml = responseHtml.ToString();

finalHtml = finalHtml.Replace(“id=\”__VIEWSTATE\””, “id=\”VIEWSTATE\””);
finalHtml = finalHtml.Replace(“id=\”__EVENTARGUMENT\””, “id=\”\”EVENTARGUMENT”);
finalHtml = finalHtml.Replace(“id=\”\”__EVENTTARGET”, “id=\”\”EVENTTARGET”);
finalHtml = finalHtml.Replace(”  />”, “>”);
finalHtml = finalHtml.Replace(” />”, “>”);
finalHtml = finalHtml.Replace(“/>”, “>”);

byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);

responseStream.Write(data, 0, data.Length);
}
}
}

The new IdFilterModule gets registered is the web.config file under httpModules.

References:

http://forum.umbraco.org/yaf_postst5965_W3C-Validation-ASPNET-ViewState-and-HTML-401.aspx

http://msdn.microsoft.com/en-us/library/system.web.httpapplication.releaserequeststate.aspx

SQL Server Express 2008 Maintenance Script

The issue I have with SQL Server Express Edition 2008 is that the SQL Agent is disabled and according to Microsoft, this has been disabled on purpose.   So, how do we schedule jobs to do such tasks as Rebuilding Indexes, Full-text Catalogs etc?   I use the Task Scheduler on Windows 2008 Server that executes a SQL script using sqlcmd -i <database script>

Here is the sample code that I use for Rebuilding indexes and catalogs:

declare @databasename varchar(max)
declare @cat varchar(max)

DECLARE database_cursor CURSOR FOR
select name from master.sys.databases
where database_id > 4 –exclude system databases

OPEN database_cursor

FETCH NEXT FROM database_cursor
INTO @databasename

WHILE @@FETCH_STATUS = 0
BEGIN

BEGIN TRY
–Below line rebuilds indexes
exec (‘USE ‘ + @databasename + ‘ EXEC sp_MSforeachtable @command1 = “ALTER INDEX ALL ON ? REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,
STATISTICS_NORECOMPUTE = ON);”‘)

exec (‘USE ‘ + @databasename + ‘ declare @cat varchar(max) select @cat = (select top 1 name from ‘ + @databasename + ‘.sys.fulltext_catalogs) if @cat is not null begin exec (”ALTER FULLTEXT CATALOG ” + @cat + ” REBUILD WITH    ACCENT_SENSITIVITY=OFF;”) end’)

END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000),
@ErrorSeverity INT,
@ErrorState INT

SET @ErrorMessage = ‘ databasename: ‘ + @databasename + ‘ ‘ + ERROR_MESSAGE();
SET @ErrorSeverity = ERROR_SEVERITY();
SET @ErrorState = ERROR_STATE();

–print @ErrorMessage
RAISERROR(@ErrorMessage,@ErrorSeverity,@ErrorState);

END CATCH

FETCH NEXT FROM database_cursor
INTO @databasename
END

CLOSE database_cursor
DEALLOCATE database_cursor Continue reading