Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / Protocols / WebServiceHandler.cs / 1305376 / WebServiceHandler.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Services.Protocols { using System.Diagnostics; using System; using System.Runtime.InteropServices; using System.Reflection; using System.IO; using System.Collections; using System.Web; using System.Web.SessionState; using System.Web.Services.Interop; using System.Configuration; using Microsoft.Win32; using System.Threading; using System.Text; using System.Web.UI; using System.Web.Util; using System.Web.UI.WebControls; using System.ComponentModel; // for CompModSwitches using System.EnterpriseServices; using System.Runtime.Remoting.Messaging; using System.Web.Services.Diagnostics; internal class WebServiceHandler { ServerProtocol protocol; Exception exception; AsyncCallback asyncCallback; ManualResetEvent asyncBeginComplete; int asyncCallbackCalls; bool wroteException; object[] parameters = null; internal WebServiceHandler(ServerProtocol protocol) { this.protocol = protocol; } // Flush the trace file after each request so that the trace output makes it to the disk. static void TraceFlush() { Debug.Flush(); } void PrepareContext() { this.exception = null; this.wroteException = false; this.asyncCallback = null; this.asyncBeginComplete = new ManualResetEvent(false); this.asyncCallbackCalls = 0; if (protocol.IsOneWay) return; HttpContext context = protocol.Context; if (context == null) return; // context is null in non-network case // we want the default to be no caching on the client int cacheDuration = protocol.MethodAttribute.CacheDuration; if (cacheDuration > 0) { context.Response.Cache.SetCacheability(HttpCacheability.Server); context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(cacheDuration)); context.Response.Cache.SetSlidingExpiration(false); // with soap 1.2 the action is a param in the content-type context.Response.Cache.VaryByHeaders["Content-type"] = true; context.Response.Cache.VaryByHeaders["SOAPAction"] = true; context.Response.Cache.VaryByParams["*"] = true; } else { context.Response.Cache.SetNoServerCaching(); context.Response.Cache.SetMaxAge(TimeSpan.Zero); } context.Response.BufferOutput = protocol.MethodAttribute.BufferResponse; context.Response.ContentType = null; } void WriteException(Exception e) { if (this.wroteException) return; if (CompModSwitches.Remote.TraceVerbose) Debug.WriteLine("Server Exception: " + e.ToString()); if (e is TargetInvocationException) { if (CompModSwitches.Remote.TraceVerbose) Debug.WriteLine("TargetInvocationException caught."); e = e.InnerException; } this.wroteException = protocol.WriteException(e, protocol.Response.OutputStream); if (!this.wroteException) throw e; } void Invoke() { PrepareContext(); protocol.CreateServerInstance(); string stringBuffer; RemoteDebugger debugger = null; if (!protocol.IsOneWay && RemoteDebugger.IsServerCallInEnabled(protocol, out stringBuffer)) { debugger = new RemoteDebugger(); debugger.NotifyServerCallEnter(protocol, stringBuffer); } try { TraceMethod caller = Tracing.On ? new TraceMethod(this, "Invoke") : null; TraceMethod userMethod = Tracing.On ? new TraceMethod(protocol.Target, protocol.MethodInfo.Name, this.parameters) : null; if (Tracing.On) Tracing.Enter(protocol.MethodInfo.ToString(), caller, userMethod); object[] returnValues = protocol.MethodInfo.Invoke(protocol.Target, this.parameters); if (Tracing.On) Tracing.Exit(protocol.MethodInfo.ToString(), caller); WriteReturns(returnValues); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "Invoke", e); if (!protocol.IsOneWay) { WriteException(e); throw; } } finally { protocol.DisposeServerInstance(); if (debugger != null) debugger.NotifyServerCallExit(protocol.Response); } } // By keeping this in a separate method we avoid jitting system.enterpriseservices.dll in cases // where transactions are not used. void InvokeTransacted() { Transactions.InvokeTransacted(new TransactedCallback(this.Invoke), protocol.MethodAttribute.TransactionOption); } void ThrowInitException() { HandleOneWayException(new Exception(Res.GetString(Res.WebConfigExtensionError), protocol.OnewayInitException), "ThrowInitException"); } void HandleOneWayException(Exception e, string method) { if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, string.IsNullOrEmpty(method) ? "HandleOneWayException" : method, e); // exceptions for one-way calls are dropped because the response is already written } protected void CoreProcessRequest() { try { bool transacted = protocol.MethodAttribute.TransactionEnabled; if (protocol.IsOneWay) { WorkItemCallback callback = null; TraceMethod callbackMethod = null; if (protocol.OnewayInitException != null) { callback = new WorkItemCallback(this.ThrowInitException); callbackMethod = Tracing.On ? new TraceMethod(this, "ThrowInitException") : null; } else { parameters = protocol.ReadParameters(); callback = transacted ? new WorkItemCallback(this.OneWayInvokeTransacted) : new WorkItemCallback(this.OneWayInvoke); callbackMethod = Tracing.On ? transacted ? new TraceMethod(this, "OneWayInvokeTransacted") : new TraceMethod(this, "OneWayInvoke") : null; } if (Tracing.On) Tracing.Information(Res.TracePostWorkItemIn, callbackMethod); WorkItem.Post(callback); if (Tracing.On) Tracing.Information(Res.TracePostWorkItemOut, callbackMethod); protocol.WriteOneWayResponse(); } else if (transacted) { parameters = protocol.ReadParameters(); InvokeTransacted(); } else { parameters = protocol.ReadParameters(); Invoke(); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "CoreProcessRequest", e); if (!protocol.IsOneWay) WriteException(e); } TraceFlush(); } private HttpContext SwitchContext(HttpContext context) { HttpContext oldContext = HttpContext.Current; HttpContext.Current = context; return oldContext; } private void OneWayInvoke() { HttpContext oldContext = null; if (protocol.Context != null) oldContext = SwitchContext(protocol.Context); try { Invoke(); } catch (Exception e) { HandleOneWayException(e, "OneWayInvoke"); } finally { if (oldContext != null) SwitchContext(oldContext); } } private void OneWayInvokeTransacted() { HttpContext oldContext = null; if (protocol.Context != null) oldContext = SwitchContext(protocol.Context); try { InvokeTransacted(); } catch (Exception e) { HandleOneWayException(e, "OneWayInvokeTransacted"); } finally { if (oldContext != null) SwitchContext(oldContext); } } private void Callback(IAsyncResult result) { if (!result.CompletedSynchronously) this.asyncBeginComplete.WaitOne(); DoCallback(result); } private void DoCallback(IAsyncResult result) { if (this.asyncCallback != null) { if (System.Threading.Interlocked.Increment(ref this.asyncCallbackCalls) == 1) { this.asyncCallback(result); } } } protected IAsyncResult BeginCoreProcessRequest(AsyncCallback callback, object asyncState) { IAsyncResult asyncResult; if (protocol.MethodAttribute.TransactionEnabled) throw new InvalidOperationException(Res.GetString(Res.WebAsyncTransaction)); parameters = protocol.ReadParameters(); if (protocol.IsOneWay) { TraceMethod callbackMethod = Tracing.On ? new TraceMethod(this, "OneWayAsyncInvoke") : null; if (Tracing.On) Tracing.Information(Res.TracePostWorkItemIn, callbackMethod); WorkItem.Post(new WorkItemCallback(this.OneWayAsyncInvoke)); if (Tracing.On) Tracing.Information(Res.TracePostWorkItemOut, callbackMethod); asyncResult = new CompletedAsyncResult(asyncState, true); if (callback != null) callback(asyncResult); } else asyncResult = BeginInvoke(callback, asyncState); return asyncResult; } private void OneWayAsyncInvoke() { if (protocol.OnewayInitException != null) HandleOneWayException(new Exception(Res.GetString(Res.WebConfigExtensionError), protocol.OnewayInitException), "OneWayAsyncInvoke"); else { HttpContext oldContext = null; if (protocol.Context != null) oldContext = SwitchContext(protocol.Context); try { BeginInvoke(new AsyncCallback(this.OneWayCallback), null); } catch (Exception e) { HandleOneWayException(e, "OneWayAsyncInvoke"); } finally { if (oldContext != null) SwitchContext(oldContext); } } } private IAsyncResult BeginInvoke(AsyncCallback callback, object asyncState) { IAsyncResult asyncResult; try { PrepareContext(); protocol.CreateServerInstance(); this.asyncCallback = callback; TraceMethod caller = Tracing.On ? new TraceMethod(this, "BeginInvoke") : null; TraceMethod userMethod = Tracing.On ? new TraceMethod(protocol.Target, protocol.MethodInfo.Name, this.parameters) : null; if (Tracing.On) Tracing.Enter(protocol.MethodInfo.ToString(), caller, userMethod); asyncResult = protocol.MethodInfo.BeginInvoke(protocol.Target, this.parameters, new AsyncCallback(this.Callback), asyncState); if (Tracing.On) Tracing.Enter(protocol.MethodInfo.ToString(), caller); if (asyncResult == null) throw new InvalidOperationException(Res.GetString(Res.WebNullAsyncResultInBegin)); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "BeginInvoke", e); // save off the exception and throw it in EndCoreProcessRequest exception = e; asyncResult = new CompletedAsyncResult(asyncState, true); this.asyncCallback = callback; this.DoCallback(asyncResult); } this.asyncBeginComplete.Set(); TraceFlush(); return asyncResult; } private void OneWayCallback(IAsyncResult asyncResult) { EndInvoke(asyncResult); } protected void EndCoreProcessRequest(IAsyncResult asyncResult) { if (asyncResult == null) return; if (protocol.IsOneWay) protocol.WriteOneWayResponse(); else EndInvoke(asyncResult); } private void EndInvoke(IAsyncResult asyncResult) { try { if (exception != null) throw (exception); object[] returnValues = protocol.MethodInfo.EndInvoke(protocol.Target, asyncResult); WriteReturns(returnValues); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "EndInvoke", e); if (!protocol.IsOneWay) WriteException(e); } finally { protocol.DisposeServerInstance(); } TraceFlush(); } void WriteReturns(object[] returnValues) { if (protocol.IsOneWay) return; // By default ASP.NET will fully buffer the response. If BufferResponse=false // then we still want to do partial buffering since each write is a named // pipe call over to inetinfo. bool fullyBuffered = protocol.MethodAttribute.BufferResponse; Stream outputStream = protocol.Response.OutputStream; if (!fullyBuffered) { outputStream = new BufferedResponseStream(outputStream, 16 * 1024); //#if DEBUG ((BufferedResponseStream)outputStream).FlushEnabled = false; //#endif } protocol.WriteReturns(returnValues, outputStream); // This will flush the buffered stream and the underlying stream. Its important // that it flushes the Response.OutputStream because we always want BufferResponse=false // to mean we are writing back a chunked response. This gives a consistent // behavior to the client, independent of the size of the partial buffering. if (!fullyBuffered) { //#if DEBUG ((BufferedResponseStream)outputStream).FlushEnabled = true; //#endif outputStream.Flush(); } } } internal class SyncSessionlessHandler : WebServiceHandler, IHttpHandler { internal SyncSessionlessHandler(ServerProtocol protocol) : base(protocol) { } public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { TraceMethod method = Tracing.On ? new TraceMethod(this, "ProcessRequest") : null; if (Tracing.On) Tracing.Enter("IHttpHandler.ProcessRequest", method, Tracing.Details(context.Request)); CoreProcessRequest(); if (Tracing.On) Tracing.Exit("IHttpHandler.ProcessRequest", method); } } internal class SyncSessionHandler : SyncSessionlessHandler, IRequiresSessionState { internal SyncSessionHandler(ServerProtocol protocol) : base(protocol) { } } internal class AsyncSessionlessHandler : SyncSessionlessHandler, IHttpAsyncHandler { internal AsyncSessionlessHandler(ServerProtocol protocol) : base(protocol) { } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object asyncState) { TraceMethod method = Tracing.On ? new TraceMethod(this, "BeginProcessRequest") : null; if (Tracing.On) Tracing.Enter("IHttpAsyncHandler.BeginProcessRequest", method, Tracing.Details(context.Request)); IAsyncResult result = BeginCoreProcessRequest(callback, asyncState); if (Tracing.On) Tracing.Exit("IHttpAsyncHandler.BeginProcessRequest", method); return result; } public void EndProcessRequest(IAsyncResult asyncResult) { TraceMethod method = Tracing.On ? new TraceMethod(this, "EndProcessRequest") : null; if (Tracing.On) Tracing.Enter("IHttpAsyncHandler.EndProcessRequest", method); EndCoreProcessRequest(asyncResult); if (Tracing.On) Tracing.Exit("IHttpAsyncHandler.EndProcessRequest", method); } } internal class AsyncSessionHandler : AsyncSessionlessHandler, IRequiresSessionState { internal AsyncSessionHandler(ServerProtocol protocol) : base(protocol) { } } class CompletedAsyncResult : IAsyncResult { object asyncState; bool completedSynchronously; internal CompletedAsyncResult(object asyncState, bool completedSynchronously) { this.asyncState = asyncState; this.completedSynchronously = completedSynchronously; } public object AsyncState { get { return asyncState; } } public bool CompletedSynchronously { get { return completedSynchronously; } } public bool IsCompleted { get { return true; } } public WaitHandle AsyncWaitHandle { get { return null; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.Services.Protocols { using System.Diagnostics; using System; using System.Runtime.InteropServices; using System.Reflection; using System.IO; using System.Collections; using System.Web; using System.Web.SessionState; using System.Web.Services.Interop; using System.Configuration; using Microsoft.Win32; using System.Threading; using System.Text; using System.Web.UI; using System.Web.Util; using System.Web.UI.WebControls; using System.ComponentModel; // for CompModSwitches using System.EnterpriseServices; using System.Runtime.Remoting.Messaging; using System.Web.Services.Diagnostics; internal class WebServiceHandler { ServerProtocol protocol; Exception exception; AsyncCallback asyncCallback; ManualResetEvent asyncBeginComplete; int asyncCallbackCalls; bool wroteException; object[] parameters = null; internal WebServiceHandler(ServerProtocol protocol) { this.protocol = protocol; } // Flush the trace file after each request so that the trace output makes it to the disk. static void TraceFlush() { Debug.Flush(); } void PrepareContext() { this.exception = null; this.wroteException = false; this.asyncCallback = null; this.asyncBeginComplete = new ManualResetEvent(false); this.asyncCallbackCalls = 0; if (protocol.IsOneWay) return; HttpContext context = protocol.Context; if (context == null) return; // context is null in non-network case // we want the default to be no caching on the client int cacheDuration = protocol.MethodAttribute.CacheDuration; if (cacheDuration > 0) { context.Response.Cache.SetCacheability(HttpCacheability.Server); context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(cacheDuration)); context.Response.Cache.SetSlidingExpiration(false); // with soap 1.2 the action is a param in the content-type context.Response.Cache.VaryByHeaders["Content-type"] = true; context.Response.Cache.VaryByHeaders["SOAPAction"] = true; context.Response.Cache.VaryByParams["*"] = true; } else { context.Response.Cache.SetNoServerCaching(); context.Response.Cache.SetMaxAge(TimeSpan.Zero); } context.Response.BufferOutput = protocol.MethodAttribute.BufferResponse; context.Response.ContentType = null; } void WriteException(Exception e) { if (this.wroteException) return; if (CompModSwitches.Remote.TraceVerbose) Debug.WriteLine("Server Exception: " + e.ToString()); if (e is TargetInvocationException) { if (CompModSwitches.Remote.TraceVerbose) Debug.WriteLine("TargetInvocationException caught."); e = e.InnerException; } this.wroteException = protocol.WriteException(e, protocol.Response.OutputStream); if (!this.wroteException) throw e; } void Invoke() { PrepareContext(); protocol.CreateServerInstance(); string stringBuffer; RemoteDebugger debugger = null; if (!protocol.IsOneWay && RemoteDebugger.IsServerCallInEnabled(protocol, out stringBuffer)) { debugger = new RemoteDebugger(); debugger.NotifyServerCallEnter(protocol, stringBuffer); } try { TraceMethod caller = Tracing.On ? new TraceMethod(this, "Invoke") : null; TraceMethod userMethod = Tracing.On ? new TraceMethod(protocol.Target, protocol.MethodInfo.Name, this.parameters) : null; if (Tracing.On) Tracing.Enter(protocol.MethodInfo.ToString(), caller, userMethod); object[] returnValues = protocol.MethodInfo.Invoke(protocol.Target, this.parameters); if (Tracing.On) Tracing.Exit(protocol.MethodInfo.ToString(), caller); WriteReturns(returnValues); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "Invoke", e); if (!protocol.IsOneWay) { WriteException(e); throw; } } finally { protocol.DisposeServerInstance(); if (debugger != null) debugger.NotifyServerCallExit(protocol.Response); } } // By keeping this in a separate method we avoid jitting system.enterpriseservices.dll in cases // where transactions are not used. void InvokeTransacted() { Transactions.InvokeTransacted(new TransactedCallback(this.Invoke), protocol.MethodAttribute.TransactionOption); } void ThrowInitException() { HandleOneWayException(new Exception(Res.GetString(Res.WebConfigExtensionError), protocol.OnewayInitException), "ThrowInitException"); } void HandleOneWayException(Exception e, string method) { if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, string.IsNullOrEmpty(method) ? "HandleOneWayException" : method, e); // exceptions for one-way calls are dropped because the response is already written } protected void CoreProcessRequest() { try { bool transacted = protocol.MethodAttribute.TransactionEnabled; if (protocol.IsOneWay) { WorkItemCallback callback = null; TraceMethod callbackMethod = null; if (protocol.OnewayInitException != null) { callback = new WorkItemCallback(this.ThrowInitException); callbackMethod = Tracing.On ? new TraceMethod(this, "ThrowInitException") : null; } else { parameters = protocol.ReadParameters(); callback = transacted ? new WorkItemCallback(this.OneWayInvokeTransacted) : new WorkItemCallback(this.OneWayInvoke); callbackMethod = Tracing.On ? transacted ? new TraceMethod(this, "OneWayInvokeTransacted") : new TraceMethod(this, "OneWayInvoke") : null; } if (Tracing.On) Tracing.Information(Res.TracePostWorkItemIn, callbackMethod); WorkItem.Post(callback); if (Tracing.On) Tracing.Information(Res.TracePostWorkItemOut, callbackMethod); protocol.WriteOneWayResponse(); } else if (transacted) { parameters = protocol.ReadParameters(); InvokeTransacted(); } else { parameters = protocol.ReadParameters(); Invoke(); } } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "CoreProcessRequest", e); if (!protocol.IsOneWay) WriteException(e); } TraceFlush(); } private HttpContext SwitchContext(HttpContext context) { HttpContext oldContext = HttpContext.Current; HttpContext.Current = context; return oldContext; } private void OneWayInvoke() { HttpContext oldContext = null; if (protocol.Context != null) oldContext = SwitchContext(protocol.Context); try { Invoke(); } catch (Exception e) { HandleOneWayException(e, "OneWayInvoke"); } finally { if (oldContext != null) SwitchContext(oldContext); } } private void OneWayInvokeTransacted() { HttpContext oldContext = null; if (protocol.Context != null) oldContext = SwitchContext(protocol.Context); try { InvokeTransacted(); } catch (Exception e) { HandleOneWayException(e, "OneWayInvokeTransacted"); } finally { if (oldContext != null) SwitchContext(oldContext); } } private void Callback(IAsyncResult result) { if (!result.CompletedSynchronously) this.asyncBeginComplete.WaitOne(); DoCallback(result); } private void DoCallback(IAsyncResult result) { if (this.asyncCallback != null) { if (System.Threading.Interlocked.Increment(ref this.asyncCallbackCalls) == 1) { this.asyncCallback(result); } } } protected IAsyncResult BeginCoreProcessRequest(AsyncCallback callback, object asyncState) { IAsyncResult asyncResult; if (protocol.MethodAttribute.TransactionEnabled) throw new InvalidOperationException(Res.GetString(Res.WebAsyncTransaction)); parameters = protocol.ReadParameters(); if (protocol.IsOneWay) { TraceMethod callbackMethod = Tracing.On ? new TraceMethod(this, "OneWayAsyncInvoke") : null; if (Tracing.On) Tracing.Information(Res.TracePostWorkItemIn, callbackMethod); WorkItem.Post(new WorkItemCallback(this.OneWayAsyncInvoke)); if (Tracing.On) Tracing.Information(Res.TracePostWorkItemOut, callbackMethod); asyncResult = new CompletedAsyncResult(asyncState, true); if (callback != null) callback(asyncResult); } else asyncResult = BeginInvoke(callback, asyncState); return asyncResult; } private void OneWayAsyncInvoke() { if (protocol.OnewayInitException != null) HandleOneWayException(new Exception(Res.GetString(Res.WebConfigExtensionError), protocol.OnewayInitException), "OneWayAsyncInvoke"); else { HttpContext oldContext = null; if (protocol.Context != null) oldContext = SwitchContext(protocol.Context); try { BeginInvoke(new AsyncCallback(this.OneWayCallback), null); } catch (Exception e) { HandleOneWayException(e, "OneWayAsyncInvoke"); } finally { if (oldContext != null) SwitchContext(oldContext); } } } private IAsyncResult BeginInvoke(AsyncCallback callback, object asyncState) { IAsyncResult asyncResult; try { PrepareContext(); protocol.CreateServerInstance(); this.asyncCallback = callback; TraceMethod caller = Tracing.On ? new TraceMethod(this, "BeginInvoke") : null; TraceMethod userMethod = Tracing.On ? new TraceMethod(protocol.Target, protocol.MethodInfo.Name, this.parameters) : null; if (Tracing.On) Tracing.Enter(protocol.MethodInfo.ToString(), caller, userMethod); asyncResult = protocol.MethodInfo.BeginInvoke(protocol.Target, this.parameters, new AsyncCallback(this.Callback), asyncState); if (Tracing.On) Tracing.Enter(protocol.MethodInfo.ToString(), caller); if (asyncResult == null) throw new InvalidOperationException(Res.GetString(Res.WebNullAsyncResultInBegin)); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "BeginInvoke", e); // save off the exception and throw it in EndCoreProcessRequest exception = e; asyncResult = new CompletedAsyncResult(asyncState, true); this.asyncCallback = callback; this.DoCallback(asyncResult); } this.asyncBeginComplete.Set(); TraceFlush(); return asyncResult; } private void OneWayCallback(IAsyncResult asyncResult) { EndInvoke(asyncResult); } protected void EndCoreProcessRequest(IAsyncResult asyncResult) { if (asyncResult == null) return; if (protocol.IsOneWay) protocol.WriteOneWayResponse(); else EndInvoke(asyncResult); } private void EndInvoke(IAsyncResult asyncResult) { try { if (exception != null) throw (exception); object[] returnValues = protocol.MethodInfo.EndInvoke(protocol.Target, asyncResult); WriteReturns(returnValues); } catch (Exception e) { if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { throw; } if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Error, this, "EndInvoke", e); if (!protocol.IsOneWay) WriteException(e); } finally { protocol.DisposeServerInstance(); } TraceFlush(); } void WriteReturns(object[] returnValues) { if (protocol.IsOneWay) return; // By default ASP.NET will fully buffer the response. If BufferResponse=false // then we still want to do partial buffering since each write is a named // pipe call over to inetinfo. bool fullyBuffered = protocol.MethodAttribute.BufferResponse; Stream outputStream = protocol.Response.OutputStream; if (!fullyBuffered) { outputStream = new BufferedResponseStream(outputStream, 16 * 1024); //#if DEBUG ((BufferedResponseStream)outputStream).FlushEnabled = false; //#endif } protocol.WriteReturns(returnValues, outputStream); // This will flush the buffered stream and the underlying stream. Its important // that it flushes the Response.OutputStream because we always want BufferResponse=false // to mean we are writing back a chunked response. This gives a consistent // behavior to the client, independent of the size of the partial buffering. if (!fullyBuffered) { //#if DEBUG ((BufferedResponseStream)outputStream).FlushEnabled = true; //#endif outputStream.Flush(); } } } internal class SyncSessionlessHandler : WebServiceHandler, IHttpHandler { internal SyncSessionlessHandler(ServerProtocol protocol) : base(protocol) { } public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { TraceMethod method = Tracing.On ? new TraceMethod(this, "ProcessRequest") : null; if (Tracing.On) Tracing.Enter("IHttpHandler.ProcessRequest", method, Tracing.Details(context.Request)); CoreProcessRequest(); if (Tracing.On) Tracing.Exit("IHttpHandler.ProcessRequest", method); } } internal class SyncSessionHandler : SyncSessionlessHandler, IRequiresSessionState { internal SyncSessionHandler(ServerProtocol protocol) : base(protocol) { } } internal class AsyncSessionlessHandler : SyncSessionlessHandler, IHttpAsyncHandler { internal AsyncSessionlessHandler(ServerProtocol protocol) : base(protocol) { } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object asyncState) { TraceMethod method = Tracing.On ? new TraceMethod(this, "BeginProcessRequest") : null; if (Tracing.On) Tracing.Enter("IHttpAsyncHandler.BeginProcessRequest", method, Tracing.Details(context.Request)); IAsyncResult result = BeginCoreProcessRequest(callback, asyncState); if (Tracing.On) Tracing.Exit("IHttpAsyncHandler.BeginProcessRequest", method); return result; } public void EndProcessRequest(IAsyncResult asyncResult) { TraceMethod method = Tracing.On ? new TraceMethod(this, "EndProcessRequest") : null; if (Tracing.On) Tracing.Enter("IHttpAsyncHandler.EndProcessRequest", method); EndCoreProcessRequest(asyncResult); if (Tracing.On) Tracing.Exit("IHttpAsyncHandler.EndProcessRequest", method); } } internal class AsyncSessionHandler : AsyncSessionlessHandler, IRequiresSessionState { internal AsyncSessionHandler(ServerProtocol protocol) : base(protocol) { } } class CompletedAsyncResult : IAsyncResult { object asyncState; bool completedSynchronously; internal CompletedAsyncResult(object asyncState, bool completedSynchronously) { this.asyncState = asyncState; this.completedSynchronously = completedSynchronously; } public object AsyncState { get { return asyncState; } } public bool CompletedSynchronously { get { return completedSynchronously; } } public bool IsCompleted { get { return true; } } public WaitHandle AsyncWaitHandle { get { return null; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ForwardPositionQuery.cs
- DataConnectionHelper.cs
- SystemResourceKey.cs
- Utils.cs
- TextEditorSpelling.cs
- TextEditorContextMenu.cs
- FusionWrap.cs
- URLAttribute.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- SpellCheck.cs
- WinFormsUtils.cs
- ProfileEventArgs.cs
- TextAction.cs
- State.cs
- XmlSignatureProperties.cs
- WhitespaceSignificantCollectionAttribute.cs
- WebServiceHandlerFactory.cs
- PackUriHelper.cs
- CellQuery.cs
- sitestring.cs
- PrintDocument.cs
- TextElementCollectionHelper.cs
- Expression.cs
- XmlSchemaDocumentation.cs
- ReplyChannelAcceptor.cs
- GPRECTF.cs
- ButtonBaseAutomationPeer.cs
- PixelFormat.cs
- XmlHierarchyData.cs
- ViewStateModeByIdAttribute.cs
- PropertyPathWorker.cs
- DoubleAnimationUsingPath.cs
- LabelAutomationPeer.cs
- WmlPhoneCallAdapter.cs
- ObjectSet.cs
- _ShellExpression.cs
- MaterialGroup.cs
- SoapAttributes.cs
- BitmapEffectGeneralTransform.cs
- RequestBringIntoViewEventArgs.cs
- VectorCollectionConverter.cs
- HttpBindingExtension.cs
- MetricEntry.cs
- DataGridCommandEventArgs.cs
- StylusPointCollection.cs
- URIFormatException.cs
- ListControl.cs
- RightsManagementErrorHandler.cs
- GrammarBuilderWildcard.cs
- ProcessHost.cs
- ZipIOExtraFieldElement.cs
- FunctionImportMapping.cs
- ToolStripPanelSelectionGlyph.cs
- ExpressionNode.cs
- PartManifestEntry.cs
- Internal.cs
- RadioButton.cs
- PropertyGridEditorPart.cs
- SessionStateContainer.cs
- PageRanges.cs
- InfoCardPolicy.cs
- FaultCallbackWrapper.cs
- TabControlEvent.cs
- XmlWrappingReader.cs
- DataChangedEventManager.cs
- EventSetterHandlerConverter.cs
- XPathCompileException.cs
- ApplicationSecurityInfo.cs
- ExceptionHandlerDesigner.cs
- XmlBoundElement.cs
- PenThreadPool.cs
- DataControlHelper.cs
- NonBatchDirectoryCompiler.cs
- CommonProperties.cs
- FrameworkElementFactory.cs
- WebPartsPersonalizationAuthorization.cs
- CollectionEditor.cs
- InputElement.cs
- TemplateNameScope.cs
- Logging.cs
- QilTargetType.cs
- BaseValidatorDesigner.cs
- GenericPrincipal.cs
- LayoutSettings.cs
- QueryComponents.cs
- LineInfo.cs
- DefaultBinder.cs
- TdsParserHelperClasses.cs
- BuildProvider.cs
- WaitHandleCannotBeOpenedException.cs
- namescope.cs
- Stylus.cs
- Serializer.cs
- CompilerCollection.cs
- ToolTipService.cs
- OleDbSchemaGuid.cs
- ControlBindingsCollection.cs
- Metafile.cs
- ScrollableControl.cs
- VisualStyleElement.cs