/// <summary> Initializes a new <see cref="WxeFunction"/>, encapsulated in a <see cref="WxeFunctionState"/> object. </summary> /// <include file='..\doc\include\ExecutionEngine\WxeHandler.xml' path='WxeHandler/CreateNewFunctionState/*' /> protected WxeFunctionState CreateNewFunctionState(HttpContext context, Type type) { ArgumentUtility.CheckNotNull("context", context); ArgumentUtility.CheckNotNull("type", type); WxeFunctionStateManager functionStates = WxeFunctionStateManager.Current; functionStates.CleanUpExpired(); WxeFunction function = (WxeFunction)Activator.CreateInstance(type); WxeFunctionState functionState = new WxeFunctionState(function, true); functionStates.Add(functionState); function.VariablesContainer.InitializeParameters(context.Request.QueryString); string returnUrlArg = context.Request.QueryString[Parameters.ReturnUrl]; string returnToSelfArg = context.Request.QueryString[Parameters.WxeReturnToSelf]; if (!string.IsNullOrEmpty(returnUrlArg)) { function.ReturnUrl = returnUrlArg; } else if (!string.IsNullOrEmpty(returnToSelfArg)) { if (bool.Parse(returnToSelfArg)) { function.ReturnUrl = context.Request.RawUrl; } } return(functionState); }
public virtual void ProcessRequest(HttpContext context) { ArgumentUtility.CheckNotNull("context", context); CheckTimeoutConfiguration(context); string functionToken = context.Request.Params[Parameters.WxeFunctionToken]; bool hasFunctionToken = !string.IsNullOrEmpty(functionToken); if (!hasFunctionToken) { _currentFunctionState = CreateNewFunctionState(context, GetType(context)); ProcessFunctionState(context, _currentFunctionState, true); } else { _currentFunctionState = ResumeExistingFunctionState(context, functionToken); if (_currentFunctionState != null) { ProcessFunctionState(context, _currentFunctionState, false); } else { context.Response.Clear(); context.Response.End(); } } }
/// <exception cref="WxePostbackOutOfSequenceException"> /// Thrown if a postback with an incorrect sequence number is handled. /// </exception> protected virtual void HandleLoadPostData(NameValueCollection postBackCollection) { ArgumentUtility.CheckNotNull("postBackCollection", postBackCollection); WxeContext wxeContext = WxeContext.Current; int postBackID = int.Parse(postBackCollection[WxePageInfo.PostBackSequenceNumberID]); if (postBackID != wxeContext.PostBackID) { CurrentPageStep.SetIsOutOfSequencePostBack(true); } string returningToken = postBackCollection[WxePageInfo.ReturningTokenID]; if (!string.IsNullOrEmpty(returningToken)) { WxeFunctionStateManager functionStates = WxeFunctionStateManager.Current; WxeFunctionState functionState = functionStates.GetItem(returningToken); if (functionState != null) { CurrentPageStep.SetReturnState(functionState.Function, true, null); _returningFunctionState = functionState; } } }
/// <summary>Initalizes a new <see cref="WxeFunctionState"/> with the passed <paramref name="function"/> and returns the associated function token.</summary> internal string GetFunctionTokenForExternalFunction(WxeFunction function, bool returnFromExecute) { bool enableCleanUp = !returnFromExecute; WxeFunctionState functionState = new WxeFunctionState(function, enableCleanUp); _functionStateManager.Add(functionState); return(functionState.FunctionToken); }
/// <summary> Removes and aborts the <paramref name="functionState"/> from the collection. </summary> /// <param name="functionState"> /// The <see cref="WxeFunctionState"/> to be removed. Must not be <see langword="null"/>. /// </param> public void Abort(WxeFunctionState functionState) { ArgumentUtility.CheckNotNull("functionState", functionState); lock (_lockObject) { Remove(functionState.FunctionToken); // WxeFunctionState is not threadsafe, thus locking the abort at this point is good practice functionState.Abort(); } }
/// <summary> Aborts the <paramref name="functionState"/> after its function has executed. </summary> /// <include file='..\doc\include\ExecutionEngine\WxeHandler.xml' path='WxeHandler/CleanUpFunctionState/*' /> protected void CleanUpFunctionState(WxeFunctionState functionState) { ArgumentUtility.CheckNotNull("functionState", functionState); bool isRootFunction = functionState.Function == functionState.Function.RootFunction; if (functionState.IsCleanUpEnabled && isRootFunction) { WxeFunctionStateManager.Current.Abort(functionState); } }
/// <summary> Cleans up expired <see cref="WxeFunctionState"/> objects in the collection. </summary> /// <returns>The remaining (i.e. not expired) function states.</returns> /// <remarks> Removes and aborts expired function states. </remarks> public int CleanUpExpired() { lock (_lockObject) { foreach (string functionToken in _functionStates.Keys.ToArray()) { if (IsExpired(functionToken)) { WxeFunctionState functionState = GetItem(functionToken); Abort(functionState); } } return(_functionStates.Count); } }
/// <summary> Adds the <paramref name="functionState"/> to the collection. </summary> /// <param name="functionState"> /// The <see cref="WxeFunctionState"/> to be added. Must not be <see langword="null"/> or aborted. /// </param> public void Add(WxeFunctionState functionState) { ArgumentUtility.CheckNotNull("functionState", functionState); if (functionState.IsAborted) { throw new ArgumentException("An aborted WxeFunctionState cannot be added to the collection.", "functionState"); } lock (_lockObject) { _functionStates.Add( functionState.FunctionToken, new WxeFunctionStateMetaData(functionState.FunctionToken, functionState.Lifetime, DateTime.Now)); _session.Add(GetSessionKeyForFunctionState(functionState.FunctionToken), functionState); } }
/// <summary> /// Sets the current <see cref="WxeContext"/> and invokes <see cref="ExecuteFunction"/> on the /// <paramref name="functionState"/>'s <see cref="WxeFunctionState.Function"/>. /// </summary> /// <include file='..\doc\include\ExecutionEngine\WxeHandler.xml' path='WxeHandler/ExecuteFunctionState/*' /> protected void ExecuteFunctionState(HttpContext context, WxeFunctionState functionState, bool isNewFunction) { ArgumentUtility.CheckNotNull("context", context); ArgumentUtility.CheckNotNull("functionState", functionState); if (functionState.IsAborted) { throw new ArgumentException("The function state " + functionState.FunctionToken + " is aborted."); } WxeContext wxeContext = new WxeContext(new HttpContextWrapper(context), WxeFunctionStateManager.Current, functionState, context.Request.QueryString); WxeContext.SetCurrent(wxeContext); functionState.PostBackID++; ExecuteFunction(functionState.Function, wxeContext, isNewFunction); }
public WxeContext(HttpContextBase context, WxeFunctionStateManager functionStateManager, WxeFunctionState functionState, NameValueCollection queryString) { ArgumentUtility.CheckNotNull("context", context); ArgumentUtility.CheckNotNull("functionStateManager", functionStateManager); ArgumentUtility.CheckNotNull("functionState", functionState); _httpContext = context; _functionStateManager = functionStateManager; _functionState = functionState; if (queryString == null) { _queryString = new NameValueCollection(); } else { _queryString = NameValueCollectionUtility.Clone(queryString); _queryString.Remove(WxeHandler.Parameters.WxeFunctionToken); } }
/// <summary> Redirects the <see cref="HttpContext.Response"/> to an optional <see cref="WxeFunction.ReturnUrl"/>. </summary> /// <include file='..\doc\include\ExecutionEngine\WxeHandler.xml' path='WxeHandler/ProcessFunctionState/*' /> protected void ProcessFunctionState(HttpContext context, WxeFunctionState functionState, bool isNewFunction) { ArgumentUtility.CheckNotNull("context", context); ArgumentUtility.CheckNotNull("functionState", functionState); ExecuteFunctionState(context, functionState, isNewFunction); // This point is only reached after the WxeFunction has completed execution. string returnUrl = functionState.Function.ReturnUrl; string executionCompletedScript = functionState.Function.ExecutionCompletedScript; CleanUpFunctionState(functionState); if (!string.IsNullOrEmpty(executionCompletedScript)) { ProcessExecutionCompletedScript(context, executionCompletedScript); } else if (!string.IsNullOrEmpty(returnUrl)) { ProcessReturnUrl(context, returnUrl); } }
/// <summary> Resumes an existing <see cref="WxeFunction"/>. </summary> /// <include file='..\doc\include\ExecutionEngine\WxeHandler.xml' path='WxeHandler/ResumeExistingFunctionState/*' /> protected WxeFunctionState ResumeExistingFunctionState(HttpContext context, string functionToken) { ArgumentUtility.CheckNotNull("context", context); ArgumentUtility.CheckNotNullOrEmpty("functionToken", functionToken); string action = context.Request.Params[Parameters.WxeAction]; bool isRefresh = StringUtility.AreEqual(action, Actions.Refresh, true); bool isAbort = StringUtility.AreEqual(action, Actions.Abort, true) || StringUtility.AreEqual(action, Actions.Cancel, true); bool isPostBackAction = isRefresh || isAbort; bool isPostRequest = string.Compare(context.Request.HttpMethod, "POST", true) == 0; if (!WxeFunctionStateManager.HasSession) { if (isPostRequest || isPostBackAction) { s_log.Error(string.Format("Error resuming WxeFunctionState {0}: The ASP.NET session has timed out.", functionToken)); throw new WxeTimeoutException("Session timeout.", functionToken); // TODO: display error message } try { return(CreateNewFunctionState(context, GetType(context))); } catch (WxeException e) { s_log.Error(string.Format("Error resuming WxeFunctionState {0}: The ASP.NET session has timed out.", functionToken)); throw new WxeTimeoutException("Session timeout.", functionToken, e); // TODO: display error message } } WxeFunctionStateManager functionStateManager = WxeFunctionStateManager.Current; if (functionStateManager.IsExpired(functionToken)) { if (isPostRequest || isPostBackAction) { s_log.Error(string.Format("Error resuming WxeFunctionState {0}: The function state has timed out or was aborted.", functionToken)); throw new WxeTimeoutException("Function Timeout.", functionToken); // TODO: display error message } try { return(CreateNewFunctionState(context, GetType(context))); } catch (WxeException e) { s_log.Error(string.Format("Error resuming WxeFunctionState {0}: The function state has timed out or was aborted.", functionToken)); throw new WxeTimeoutException("Function Timeout.", functionToken, e); // TODO: display error message } } WxeFunctionState functionState = functionStateManager.GetItem(functionToken); if (functionState.IsAborted) { s_log.Error(string.Format("Error resuming WxeFunctionState {0}: The function state has been aborted.", functionState.FunctionToken)); throw new InvalidOperationException(string.Format("WxeFunctionState {0} is aborted.", functionState.FunctionToken)); // TODO: display error message } if (isRefresh) { functionStateManager.Touch(functionToken); functionStateManager.CleanUpExpired(); return(null); } else if (isAbort) { functionStateManager.CleanUpExpired(); functionStateManager.Abort(functionState); return(null); } else { functionStateManager.Touch(functionToken); functionStateManager.CleanUpExpired(); if (functionState.Function == null) { throw new WxeException(string.Format("Function missing in WxeFunctionState {0}.", functionState.FunctionToken)); } return(functionState); } }