ViewState cleanup issue


Description

In the default configuration, ViewState information for Sitecore Client applications is stored in the server's file system.

Sitecore XP has a background job that cleans up ViewState files from a disk on a regular basis. If a user is logged in to a Sitecore Client for a long period of time, and the ViewState files for their session are deleted from the disk, the user might experience an unhandled exception when working with the Sitecore Client.

Exception 1:

[ArgumentNullException]: Value cannot be null.
Parameter name: stream
at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
at System.IO.StreamReader..ctor(Stream stream, Boolean detectEncodingFromByteOrderMarks)
at XamlPageStatePersister.Load()
at System.Web.UI.Page.LoadPageStateFromPersistenceMedium()
at System.Web.UI.Page.LoadAllState()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
[HttpUnhandledException]: Exception of type 'System.Web.HttpUnhandledException' was thrown.
at System.Web.UI.Page.HandleError(Exception e)
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.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Exception 2:

[NullReferenceException: Object reference not set to an instance of an object.]
   Sitecore.Shell.Applications.ContentManager.ContentEditorForm.OnLoad(EventArgs e) +1495
 
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +0
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) +1255
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +38
   Sitecore.Reflection.ReflectionUtil.InvokeMethod(MethodInfo method, Object[] parameters, Object obj) +91
   Sitecore.Web.UI.Sheer.ClientPage.OnLoad(EventArgs e) +332
   System.Web.UI.Control.LoadRecursive() +66
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2428

Exception 3:

[ArgumentNullException: Value cannot be null.
Parameter name: inputString]
   System.Web.UI.ObjectStateFormatter.Deserialize(String inputString, Purpose purpose) +835
   System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) +22
   XamlPageStatePersister.Load() +155
   System.Web.UI.Page.LoadPageStateFromPersistenceMedium() +58
   System.Web.UI.Page.LoadAllState() +46
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2441

Solution

To resolve the issue, set the maximum age of the ViewState files to the value that exceeds the maximum time the user can be logged in to the Sitecore Client, for example:

<agent type="Sitecore.Tasks.CleanupAgent" method="Run" interval="06:00:00">
  <files hint="raw:AddCommand">
    <remove folder="$(dataFolder)/viewstate" pattern="*.txt" maxAge="2.00:00:00" recursive="true" />
  </files>
</agent>