Monday, March 05, 2007

VIewState issue in creating a Word Doc from Rendered ASPX

Early last week, i was involved in a pretty interesting assignment of creating a word document with some dynamically created data on the click of a button from an ASPX Page. I created a template aspx page for the word Document. In the load of the page, i took all the values from session and loaded the labels. Did a Server.Execute("Page.aspx", StringWriter) from the button click event. the StringWriter object was converted to a byte array and written in to the HTTP Stream using Response.BinaryWrite(byte[]). Everything went well and the word document was opened . But there was an uninvited guest in the word document when i opened it. it was a text box on top of the word doc with some junk values in it. After some investigations, I understood that it was the Viewstate variable created as an inside the rendedred HTML. I turned off viewstate by doing Page.EnableViewState = False. And tested again... but now also the text box appeared in the word document , but with no values in it. Even if you turn off ViewState, the viewstate variable will be created in the rendered HTML with no values in it. Workarounds:Now, there are 2 workarounds for this issue.(As suggested by 2 Avanade comunity members) 1. Use a usercontrol with the doc template created in it. Load values in the load event of the control. On Pag Load event, render the usercontrol using UserControl.RenderControl();This worked out perfectly.
2. Either use Server.Execute("Page.aspx", StringWriter) from another page or this.Render(HTMLTextWriter) from the current page and get the rendered HTML of the Word Doc page in a StringWriter, Convert it to a string and find out Viewstate declaration inside the string and remove it. We choose this method as we had some problem in creating usercontrol in the complex architecture.
I wrote the following method to remove ViewState from the rendered HTML:

//Method to remove __VIEWSTATE and stateTarget variables
private string RemoveInputFieldsFromRenderedHTML(string pageData)
{//pageDate variable contails the rendered HTML from the stringwriter.
int startIndex;
int endIndex;
//Variable to store the length of closing tag of Viewstate

string newPageData = "";
string viewStateStartTag = "string viewStateEndTag = "\" />";int lengthOfClosingTag = 4; //This can be re written as viewStateEndTag.Length()
startIndex = pageData.IndexOf(viewStateStartTag);
endIndex = pageData.IndexOf(viewStateEndTag,startIndex);
if(startIndex > 0)
newPageData = pageData.Remove( startIndex,(endIndex + lengthOfClosingTag) - startIndex);

return newPageData;
}


Hope this piece of code will be useful to somebody someday....