Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- LazyTextWriterCreator.cs
- DesignerForm.cs
- XmlRawWriterWrapper.cs
- WeakReferenceEnumerator.cs
- ErrorRuntimeConfig.cs
- TextEffect.cs
- SyndicationSerializer.cs
- Operand.cs
- Debug.cs
- XPathNavigator.cs
- HtmlWindowCollection.cs
- HideDisabledControlAdapter.cs
- AdornerPresentationContext.cs
- documentsequencetextview.cs
- BitmapEffectInput.cs
- LookupBindingPropertiesAttribute.cs
- EndOfStreamException.cs
- CommandDevice.cs
- OleDbConnectionFactory.cs
- SapiInterop.cs
- ContentPlaceHolder.cs
- ProviderException.cs
- SqlBuffer.cs
- ListControlConvertEventArgs.cs
- CustomCategoryAttribute.cs
- Win32.cs
- RtfToXamlReader.cs
- PeerNameRecord.cs
- TextBoxRenderer.cs
- Privilege.cs
- MinimizableAttributeTypeConverter.cs
- SafeCertificateContext.cs
- TextEditor.cs
- CodeMethodReturnStatement.cs
- StringResourceManager.cs
- SmtpNetworkElement.cs
- FormViewInsertEventArgs.cs
- RawAppCommandInputReport.cs
- LocationSectionRecord.cs
- CheckBox.cs
- IApplicationTrustManager.cs
- PrintEvent.cs
- TextProviderWrapper.cs
- EndpointIdentityConverter.cs
- GroupDescription.cs
- SimpleWorkerRequest.cs
- RSAProtectedConfigurationProvider.cs
- UserControlBuildProvider.cs
- InstanceCreationEditor.cs
- Preprocessor.cs
- XsdBuilder.cs
- CompilerState.cs
- MexTcpBindingElement.cs
- WmiPutTraceRecord.cs
- WebPartExportVerb.cs
- TabPage.cs
- X509RecipientCertificateServiceElement.cs
- ContractInstanceProvider.cs
- ImmComposition.cs
- GroupItem.cs
- XPathCompileException.cs
- DataGridSortingEventArgs.cs
- FieldToken.cs
- WindowsToolbarAsMenu.cs
- ByteConverter.cs
- EventSchemaTraceListener.cs
- ProviderConnectionPointCollection.cs
- CredentialCache.cs
- ArrayConverter.cs
- SqlVisitor.cs
- AddInControllerImpl.cs
- ManualResetEvent.cs
- StructuredType.cs
- OleServicesContext.cs
- ManifestBasedResourceGroveler.cs
- _ChunkParse.cs
- BufferModeSettings.cs
- CqlQuery.cs
- ActivityMarkupSerializationProvider.cs
- StreamMarshaler.cs
- MembershipPasswordException.cs
- EntityDataSourceWrapper.cs
- SerializationInfoEnumerator.cs
- ClientSettingsSection.cs
- UniqueIdentifierService.cs
- RightsManagementEncryptedStream.cs
- NegotiationTokenProvider.cs
- Cursors.cs
- Model3DGroup.cs
- SelectionProcessor.cs
- NamedPermissionSet.cs
- SRef.cs
- DataViewSettingCollection.cs
- TextBox.cs
- MapPathBasedVirtualPathProvider.cs
- HttpFileCollectionWrapper.cs
- HMACSHA256.cs
- PLINQETWProvider.cs
- ProviderCommandInfoUtils.cs
- EntityViewGenerationAttribute.cs