void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) { if (result.CompletedSynchronously) { return; } AsyncWebMethodState state = result.AsyncState as AsyncWebMethodState; if (result.IsCompleted) { MethodInfo endMethod = state.MethodDef.EndMethod.MethodType; try { object returnValue = endMethod.Invoke(state.Target, new object[] { result }); GenerateResponse(returnValue, state.Context, state.MethodDef, state.ServiceDef); } catch (Exception x) { WebServiceHelper.WriteExceptionJsonString(state.Context, x, state.ServiceDef.Serializer); } finally { state.Target.Dispose(); } state.Dispose(); } }
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { // Proper Content-Type header must be present in order to make a REST call if (!IsRestMethodCall(context.Request)) { return(GenerateErrorResponse(context, "Not a valid REST call", extraData)); } string methodName = context.Request.PathInfo.Substring(1); WebServiceDef wsDef = WebServiceHelper.GetWebServiceType(context, context.Request.FilePath); WebMethodDef methodDef = wsDef.Methods[methodName]; if (null == methodDef) { return(GenerateErrorResponse(context, "Web method not supported: " + methodName, extraData)); } // GET request will only be allowed if the method says so if (context.Request.HttpMethod == "GET" && !methodDef.IsGetAllowed) { return(GenerateErrorResponse(context, "Http Get method not supported", extraData)); } context.Response.Filter = new ResponseFilter(context.Response); // If the method does not have a BeginXXX and EndXXX pair, execute it synchronously if (!methodDef.HasAsyncMethods) { // Do synchronous call ExecuteMethod(context, methodDef, wsDef); // Return a result that says method was executed synchronously return(new AsmxHandlerSyncResult(extraData)); } else { // Call the Begin method of web service IDisposable target = Activator.CreateInstance(wsDef.WSType) as IDisposable; WebMethodDef beginMethod = methodDef.BeginMethod; int allParameterCount = beginMethod.InputParametersWithAsyc.Count; IDictionary <string, object> inputValues = GetRawParams(context, beginMethod.InputParameters, wsDef.Serializer); object[] parameterValues = StrongTypeParameters(inputValues, beginMethod.InputParameters); // Prepare the list of parameter values which will also include the AsyncCallback and the state object[] parameterValuesWithAsync = new object[allParameterCount]; Array.Copy(parameterValues, parameterValuesWithAsync, parameterValues.Length); // Populate last two parameters with async callback and state parameterValuesWithAsync[allParameterCount - 2] = cb; AsyncWebMethodState webMethodState = new AsyncWebMethodState(methodName, target, wsDef, methodDef, context, extraData); parameterValuesWithAsync[allParameterCount - 1] = webMethodState; try { // Invoke the BeginXXX method and ensure the return result has AsyncWebMethodState. This state // contains context and other information which we need in oreder to call the EndXXX IAsyncResult result = beginMethod.MethodType.Invoke(target, parameterValuesWithAsync) as IAsyncResult; // If execution has completed synchronously within the BeginXXX function, then generate response // immediately. There's no need to call EndXXX if (result.CompletedSynchronously) { object returnValue = result.AsyncState; GenerateResponse(returnValue, context, methodDef, wsDef); target.Dispose(); return(new AsmxHandlerSyncResult(extraData)); } else { if (result.AsyncState is AsyncWebMethodState) { return(result); } else { throw new InvalidAsynchronousStateException("The state passed in the " + beginMethod.MethodName + " must inherit from " + typeof(AsyncWebMethodState).FullName); } } } catch (Exception x) { target.Dispose(); WebServiceHelper.WriteExceptionJsonString(context, x, wsDef.Serializer); return(new AsmxHandlerSyncResult(extraData)); } } }
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { // Proper Content-Type header must be present in order to make a REST call if (!IsRestMethodCall(context.Request)) { return GenerateErrorResponse(context, "Not a valid REST call", extraData); } string methodName = context.Request.PathInfo.Substring(1); WebServiceDef wsDef = WebServiceHelper.GetWebServiceType(context, context.Request.FilePath); WebMethodDef methodDef = wsDef.Methods[methodName]; if (null == methodDef) return GenerateErrorResponse(context, "Web method not supported: " + methodName, extraData); // GET request will only be allowed if the method says so if (context.Request.HttpMethod == "GET" && !methodDef.IsGetAllowed) return GenerateErrorResponse(context, "Http Get method not supported", extraData); context.Response.Filter = new ResponseFilter(context.Response); // If the method does not have a BeginXXX and EndXXX pair, execute it synchronously if (!methodDef.HasAsyncMethods) { // Do synchronous call ExecuteMethod(context, methodDef, wsDef); // Return a result that says method was executed synchronously return new AsmxHandlerSyncResult(extraData); } else { // Call the Begin method of web service IDisposable target = Activator.CreateInstance(wsDef.WSType) as IDisposable; WebMethodDef beginMethod = methodDef.BeginMethod; int allParameterCount = beginMethod.InputParametersWithAsyc.Count; IDictionary<string, object> inputValues = GetRawParams(context, beginMethod.InputParameters, wsDef.Serializer); object[] parameterValues = StrongTypeParameters(inputValues, beginMethod.InputParameters); // Prepare the list of parameter values which will also include the AsyncCallback and the state object[] parameterValuesWithAsync = new object[allParameterCount]; Array.Copy(parameterValues, parameterValuesWithAsync, parameterValues.Length); // Populate last two parameters with async callback and state parameterValuesWithAsync[allParameterCount - 2] = cb; AsyncWebMethodState webMethodState = new AsyncWebMethodState(methodName, target, wsDef, methodDef, context, extraData); parameterValuesWithAsync[allParameterCount - 1] = webMethodState; try { // Invoke the BeginXXX method and ensure the return result has AsyncWebMethodState. This state // contains context and other information which we need in oreder to call the EndXXX IAsyncResult result = beginMethod.MethodType.Invoke(target, parameterValuesWithAsync) as IAsyncResult; // If execution has completed synchronously within the BeginXXX function, then generate response // immediately. There's no need to call EndXXX if (result.CompletedSynchronously) { object returnValue = result.AsyncState; GenerateResponse(returnValue, context, methodDef, wsDef); target.Dispose(); return new AsmxHandlerSyncResult(extraData); } else { if (result.AsyncState is AsyncWebMethodState) return result; else throw new InvalidAsynchronousStateException("The state passed in the " + beginMethod.MethodName + " must inherit from " + typeof(AsyncWebMethodState).FullName); } } catch (Exception x) { target.Dispose(); WebServiceHelper.WriteExceptionJsonString(context, x, wsDef.Serializer); return new AsmxHandlerSyncResult(extraData); } } }
public AsyncWebMethodState(AsyncWebMethodState s) : this(s.MethodName, s.Target, s.ServiceDef, s.MethodDef, s.Context, s.ExtraData) { }