利用正则表达式优化WebForms输出

WebForms技术在开发Web应用程序时提供了许多便利,但其输出往往包含冗长的ID和不必要的ViewState,这不仅增加了页面的体积,还可能影响性能。本文将探讨如何通过正则表达式来优化WebForms的输出,包括去除ViewState、处理嵌套表单以及缩短ID等技巧。

页面输出的常见问题

WebForms中,页面输出常常包含一些冗余的内容,例如过长的ID和ViewState。这些内容不仅增加了页面的体积,还可能影响页面的性能。例如,一个简单的元素可能会被赋予一个非常长的ID:

<span id="accounts_overview_body_quickAction_quickActionTitleLabel"></span>

此外,ViewState虽然在某些情况下非常有用,但在不需要时,它的存在会增加页面的体积,并且可能导致一些浏览器无法正常工作。

控制页面输出

通过重写页面的Render事件,可以在内容发送给用户之前对其进行操作。这为提供了一个机会,可以在内容被发送之前对其进行修改。以下是实现这一操作的基本步骤:

protected override void Render(HtmlTextWriter writer) { // render our output StringWriter output = new StringWriter(); HtmlTextWriter html = new HtmlTextWriter(output); base.Render(html); // get the rendered string string rendered = output.ToString(); // Make our changes // ... discussed shortly // cleanup our writers html.Dispose(); output.Dispose(); // then write it writer.Write(rendered); }

通过这种方式,可以在内容被发送给用户之前对其进行修改。

去除ViewState

在某些页面上,可能并不需要ViewState。例如,如果页面只显示一些产品信息或图片,并且用户不需要对这些内容进行回传,那么ViewState就显得多余。可以使用正则表达式来去除页面中的ViewState:

rendered = Regex.Replace( rendered, "]*>", string.Empty, RegexOptions.IgnoreCase );

这段代码会从页面中完全去除ViewState。如果需要去除其他类似的内容,例如__EVENTSTATE,可以通过修改正则表达式来实现。

处理嵌套表单

WebForms中,如果想在页面中使用其他表单,那么这些表单必须位于Page Form之外。这是因为并非所有的浏览器都支持嵌套表单。可以通过正则表达式来去除页面中的Page Form,同时保留其他表单:

// find all the forms and closed elements MatchCollection matches = Regex.Matches( rendered, "]*>", RegexOptions.IgnoreCase ); // create the expression to match for the ID Regex expectedId = new Regex( string.Format( "id=\"?({0}|aspnetForm)\"?", this.Form.ID ), RegexOptions.IgnoreCase ); // expression to check for a close of a form Regex closeForm = new Regex( @"", RegexOptions.IgnoreCase ); // loop through and remove the page form Match open = null; Match close = null; int depth = 0; for (int i = 0; i < matches.Count; i++) { Match match = matches[i]; // check if this is the page form if (expectedId.IsMatch(match.Value) && !(open is Match)) { open = match; } // if we aren't tracking yet, just continue if (!(open is Match)) continue; // change the direction of the nesting depth += closeForm.IsMatch(match.Value) ? -1 : 1; // if the nesting is back to zero we can assume this // is the correct tag if (depth == 0) { close = match; break; } } // remove the tags - make sure to start with the close tag // since this will affect the index of the Matches if (open is Match && close is Match) { rendered = rendered.Remove(close.Index, close.Length); rendered = rendered.Remove(open.Index, open.Length); }

通过这种方式,可以去除页面中的Page Form,同时保留其他表单,以便它们可以正常处理回传。

缩短ID

ASP.NET 4.0提供了一些功能,帮助开发者将有意义的ID推送到客户端。目前,ID是通过使用父级、父级、父级等ID生成的,这在避免命名冲突方面很有用,但如果在客户端进行操作,这可能会带来问题。此外,有时可能会在一些并不打算操作的元素上得到ID,这完全是浪费空间。

可以使用正则表达式来修改页面上的ID:

// lastly, drop any unwanted IDs MatchCollection extraIds = Regex.Matches( rendered, @"<[^>]*actualId=""(?[^""]*)""[^>]*>", RegexOptions.IgnoreCase ); // loop backwards to avoid affecting indexes on the matches for (int i = extraIds.Count; i-- > 0; ) { Match extra = extraIds[i]; // drop the unwanted parts string newElement = extra.Value; string newID = extra.Groups["id"].Value; // lastly, remove the actual ID field newElement = Regex.Replace( newElement, @"actualId=""""[^""]*""""?", string.Empty, RegexOptions.IgnoreCase ); // if the ID is blank, just remove it newElement = Regex.Replace(newElement, @"(id|name)=""""[^""]*""""?", (str) => { if (string.IsNullOrEmpty(newID)) { return string.Empty; } return string.Concat( str.Value.StartsWith("id", StringComparison.OrdinalIgnoreCase) ? "id" : "name", "=\"", newID, "\" "); }); // finally, replace the new string rendered = rendered.Remove(extra.Index, extra.Length); rendered = rendered.Insert(extra.Index, newElement); }

这是一个定制的解决方案。可以通过这种方式,在控件上添加“actualId”属性,然后id和name属性将更新以反映该值。此外,actualId属性将完全从元素中移除。

绝对权力导致腐败

进入渲染输出并对其进行修改,以改变发送给客户端的内容,这是非常有趣的。有很大的权力来完全改变内容的外观。但是要小心——改变得越多,就越有可能破坏ASP.NET的工作方式。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485