There are documented articles about moving viewstate to the bottom of the page for better SEO due to search engines only reading the first x bytes of a page.
http://professionalaspnet.com/archive/2006/07/30/Moving-ViewState-to-Optimize-Web-Pages.aspx
http://www.hanselman.com/blog/MovingViewStateToTheBottomOfThePage.aspx
http://scottonwriting.net/sowBlog/posts/1323.aspx
I was wondering if we can add an option in the page settings to enable moving viewstate (or disable it if a page does not like it).
Add a new property to PageSettings MoveViewstate
Then in the mojoBasePage.cs file add the following method:
private string MoveHiddenFieldsToBottom(string html)
{
string sPattern = "<input type=\"hidden\".*/*>|<input type=\"hidden\".*></input>";
MatchCollection mc = Regex.Matches(html, sPattern, RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace);
StringBuilder sb = new StringBuilder();
foreach (Match m in mc)
{
sb.AppendLine(m.Value);
html = html.Replace(m.Value, string.Empty);
}
return html.Replace("</form>", sb.ToString() + "</form>");
}
The code above is the The Beer House project and associated ASP.Net book.
Wire this method up in the Render method like so:
protected override void Render(HtmlTextWriter writer)
{
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlWriter = null;
string html = string.Empty;
if (!SiteUtils.UrlWasReWritten())
{
if (currentPage.MoveViewstate)
{
htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
html = MoveHiddenFieldsToBottom(stringWriter.ToString());
writer.Write(html);
}
else
{
base.Render(writer);
}
return;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Custom HtmlTextWriter to fix Form Action
* Based on Jesse Ezell's "Fixing Microsoft's Bugs: URL Rewriting"
* http://weblogs.asp.net/jezell/archive/2004/03/15/90045.aspx
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// this removes the action attribute from the form
// so that it posts back correctly when using url re-writing
//string rawUrl = Request.RawUrl;
string action = Request.RawUrl;
//if (Request.RawUrl.IndexOf(".aspx") > -1)
//{
// action = Path.GetFileName(Request.RawUrl.Substring(0, Request.RawUrl.IndexOf(".aspx") + 5));
//}
//else
//{
// action = Path.GetFileName(Request.RawUrl);
//}
// we need to append the query string to the form action
// otherwise the params won't be available when the form posts back
// example if editing an event ~/EventCalendarEdit.aspx??mid=4&pageid=3
// if the form action is merely "EventCalendarEdit.aspx" we won't have the
// mid and pageid params on postback. querystring is only available in get requests
// unless the form action includes it, then its also available in post requests
if (
(appendQueryStringToAction)
&& (action.IndexOf("?") == -1)
&& (Request.QueryString.Count > 0)
)
{
action += "?" + Request.QueryString.ToString();
}
if (writer.GetType() == typeof(HtmlTextWriter))
{
writer = new MojoHtmlTextWriter(writer, action);
}
else if (writer.GetType() == typeof(Html32TextWriter))
{
writer = new MojoHtml32TextWriter(writer, action);
}
if (currentPage.MoveViewstate)
{
htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
html = MoveHiddenFieldsToBottom(stringWriter.ToString());
writer.Write(html);
}
else
{
base.Render(writer);
}
}
I have it running successfully locally, (Except the Page Settings changes), but have not tested with all features.