C# – asp.net Invalid character in a Base-64 string


I have a c# mobile site and have a problem with some of mobile clients. I have posted a trace below but basically browser of phone or wap gateway that phone connects to internet url encodes viewstate hidden input in the form.




so viewstate fails.

Is there anyway to override and urldecode viewstate info before proccessing?

System.Web.HttpException: The state information is invalid for this page and might be corrupted. ---> System.Web.UI.ViewStateException: Invalid viewstate. 
 Client IP:
 Port: 37172
 User-Agent: SCH-R430 UP.Browser/ (GUI) MMP/2.0
 Path: /mobile/Inbox.aspx ---> System.FormatException: Invalid character in a Base-64 string.
   at System.Convert.FromBase64String(String s)
   at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
   at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState)
   at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState)
   at System.Web.UI.HiddenFieldPageStatePersister.Load()
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError)
   at System.Web.UI.ViewStateException.ThrowViewStateError(Exception inner, String persistedState)
   at System.Web.UI.HiddenFieldPageStatePersister.Load()
   at System.Web.UI.Page.LoadPageStateFromPersistenceMedium()
   at System.Web.UI.Page.LoadAllState()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.mobile_inbox_aspx.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Best Solution

You can implement a custom ViewStatePersister object which handles this. You probably want to derive it from HiddenFieldPageStatePersister. Take a look at this article which shows how to implement compression on top of ViewState, but is very similar to what you need to do.

There's a little bit of hackiness involved: you'll need to use reflection to set a field of the StateFormatter base class which is, contrary to what the MSDN docs say, not marked as virtual so can't be overridden without reflection.