Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / DispatchOperationRuntime.cs / 3 / DispatchOperationRuntime.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System; using System.ServiceModel.Channels; using System.ServiceModel; using System.Reflection; using System.Security.Principal; using System.Web.Security; using System.Collections; using System.ServiceModel.Diagnostics; using System.Globalization; using System.Security; using System.Diagnostics; class DispatchOperationRuntime { static AsyncCallback invokeCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(DispatchOperationRuntime.InvokeCallback)); readonly string action; readonly ICallContextInitializer[] callContextInitializers; readonly IDispatchFaultFormatter faultFormatter; readonly IDispatchMessageFormatter formatter; readonly ImpersonationOption impersonation; readonly IParameterInspector[] inspectors; readonly IOperationInvoker invoker; readonly bool isTerminating; readonly bool isSynchronous; readonly string name; readonly ImmutableDispatchRuntime parent; readonly bool releaseInstanceAfterCall; readonly bool releaseInstanceBeforeCall; readonly string replyAction; readonly bool transactionAutoComplete; readonly bool transactionRequired; readonly bool deserializeRequest; readonly bool serializeReply; readonly bool isOneWay; readonly bool disposeParameters; internal DispatchOperationRuntime(DispatchOperation operation, ImmutableDispatchRuntime parent) { if (operation == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operation"); } if (parent == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parent"); } if (operation.Invoker == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RuntimeRequiresInvoker0))); } this.disposeParameters = ((operation.AutoDisposeParameters) && (!operation.HasNoDisposableParameters)); this.parent = parent; this.callContextInitializers = EmptyArray.ToArray(operation.CallContextInitializers); this.inspectors = EmptyArray .ToArray(operation.ParameterInspectors); this.faultFormatter = operation.FaultFormatter; this.impersonation = operation.Impersonation; this.deserializeRequest = operation.DeserializeRequest; this.serializeReply = operation.SerializeReply; this.formatter = operation.Formatter; this.invoker = operation.Invoker; try { this.isSynchronous = operation.Invoker.IsSynchronous; } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } this.isTerminating = operation.IsTerminating; this.action = operation.Action; this.name = operation.Name; this.releaseInstanceAfterCall = operation.ReleaseInstanceAfterCall; this.releaseInstanceBeforeCall = operation.ReleaseInstanceBeforeCall; this.replyAction = operation.ReplyAction; this.isOneWay = operation.IsOneWay; this.transactionAutoComplete = operation.TransactionAutoComplete; this.transactionRequired = operation.TransactionRequired; if (this.formatter == null && (deserializeRequest || serializeReply)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DispatchRuntimeRequiresFormatter0, this.name))); } if ((operation.Parent.InstanceProvider == null) && (operation.Parent.Type != null)) { SyncMethodInvoker sync = this.invoker as SyncMethodInvoker; if (sync != null) { this.ValidateInstanceType(operation.Parent.Type, sync.Method); } AsyncMethodInvoker async = this.invoker as AsyncMethodInvoker; if (async != null) { this.ValidateInstanceType(operation.Parent.Type, async.BeginMethod); this.ValidateInstanceType(operation.Parent.Type, async.EndMethod); } } } internal string Action { get { return this.action; } } internal ICallContextInitializer[] CallContextInitializers { get { return this.callContextInitializers; } } internal bool DisposeParameters { get { return this.disposeParameters; } } internal bool HasDefaultUnhandledActionInvoker { get { return (this.invoker is DispatchRuntime.UnhandledActionInvoker); } } internal bool SerializeReply { get { return this.serializeReply; } } internal IDispatchFaultFormatter FaultFormatter { get { return this.faultFormatter; } } internal IDispatchMessageFormatter Formatter { get { return this.formatter; } } internal ImpersonationOption Impersonation { get { return this.impersonation; } } internal IOperationInvoker Invoker { get { return this.invoker; } } internal bool IsSynchronous { get { return this.isSynchronous; } } internal bool IsOneWay { get { return this.isOneWay; } } internal bool IsTerminating { get { return this.isTerminating; } } internal string Name { get { return this.name; } } internal IParameterInspector[] ParameterInspectors { get { return this.inspectors; } } internal ImmutableDispatchRuntime Parent { get { return this.parent; } } internal bool ReleaseInstanceAfterCall { get { return this.releaseInstanceAfterCall; } } internal bool ReleaseInstanceBeforeCall { get { return this.releaseInstanceBeforeCall; } } internal string ReplyAction { get { return this.replyAction; } } internal bool TransactionAutoComplete { get { return this.transactionAutoComplete; } } internal bool TransactionRequired { get { return this.transactionRequired; } } void DeserializeInputs(ref MessageRpc rpc) { bool success = false; try { try { rpc.InputParameters = this.Invoker.AllocateInputs(); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } if (ErrorBehavior.ShouldRethrowExceptionAsIs(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } try { if (this.deserializeRequest) { this.Formatter.DeserializeRequest(rpc.Request, rpc.InputParameters); } else { rpc.InputParameters[0] = rpc.Request; } success = true; } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } if (ErrorBehavior.ShouldRethrowExceptionAsIs(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } } finally { rpc.DidDeserializeRequestBody = (rpc.Request.State != MessageState.Created); if (!success && MessageLogger.LoggingEnabled) { MessageLogger.LogMessage(ref rpc.Request, MessageLoggingSource.Malformed); } } } void InitializeCallContext(ref MessageRpc rpc) { if (this.CallContextInitializers.Length > 0) { InitializeCallContextCore(ref rpc); } } void InitializeCallContextCore(ref MessageRpc rpc) { IClientChannel channel = rpc.Channel.Proxy as IClientChannel; int offset = this.Parent.CallContextCorrelationOffset; try { for (int i = 0; i < rpc.Operation.CallContextInitializers.Length; i++) { ICallContextInitializer initializer = this.CallContextInitializers[i]; rpc.Correlation[offset + i] = initializer.BeforeInvoke(rpc.InstanceContext, channel, rpc.Request); } } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } if (ErrorBehavior.ShouldRethrowExceptionAsIs(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } } void UninitializeCallContext(ref MessageRpc rpc) { if (this.CallContextInitializers.Length > 0) { UninitializeCallContextCore(ref rpc); } } void UninitializeCallContextCore(ref MessageRpc rpc) { IClientChannel channel = rpc.Channel.Proxy as IClientChannel; int offset = this.Parent.CallContextCorrelationOffset; try { for (int i = this.CallContextInitializers.Length - 1; i >= 0; i--) { ICallContextInitializer initializer = this.CallContextInitializers[i]; initializer.AfterInvoke(rpc.Correlation[offset + i]); } } catch (Exception e) { // thread-local storage may be corrupt DiagnosticUtility.FailFast(string.Format(CultureInfo.InvariantCulture, "ICallContextInitializer.BeforeInvoke threw an exception of type {0}: {1}", e.GetType(), e.Message)); } } void InspectInputs(ref MessageRpc rpc) { if (this.ParameterInspectors.Length > 0) { InspectInputsCore(ref rpc); } } void InspectInputsCore(ref MessageRpc rpc) { int offset = this.Parent.ParameterInspectorCorrelationOffset; for (int i = 0; i < this.ParameterInspectors.Length; i++) { IParameterInspector inspector = this.ParameterInspectors[i]; rpc.Correlation[offset + i] = inspector.BeforeCall(this.Name, rpc.InputParameters); } } void InspectOutputs(ref MessageRpc rpc) { if (this.ParameterInspectors.Length > 0) { InspectOutputsCore(ref rpc); } } void InspectOutputsCore(ref MessageRpc rpc) { int offset = this.Parent.ParameterInspectorCorrelationOffset; for (int i = this.ParameterInspectors.Length - 1; i >= 0; i--) { IParameterInspector inspector = this.ParameterInspectors[i]; inspector.AfterCall(this.Name, rpc.OutputParameters, rpc.ReturnParameter, rpc.Correlation[offset + i]); } } /// /// Critical - calls SecurityCritical method StartImpersonation /// Safe - manages the result of impersonation and properly Disposes it /// [DebuggerStepperBoundary] [SecurityCritical, SecurityTreatAsSafe] internal void InvokeBegin(ref MessageRpc rpc) { if (rpc.Error == null) { try { this.InitializeCallContext(ref rpc); object target = rpc.Instance; this.DeserializeInputs(ref rpc); this.InspectInputs(ref rpc); ValidateMustUnderstand(ref rpc); IAsyncResult result = null; IDisposable impersonationContext = null; IPrincipal originalPrincipal = null; bool isThreadPrincipalSet = false; try { if (this.parent.SecurityImpersonation != null) { this.parent.SecurityImpersonation.StartImpersonation(ref rpc, out impersonationContext, out originalPrincipal, out isThreadPrincipalSet); } if (this.isSynchronous) { rpc.ReturnParameter = this.Invoker.Invoke(target, rpc.InputParameters, out rpc.OutputParameters); } else { bool isBeginSuccessful = false; IResumeMessageRpc resumeRpc = rpc.Pause(); try { result = this.Invoker.InvokeBegin(target, rpc.InputParameters, invokeCallback, resumeRpc); isBeginSuccessful = true; // if the call above actually went async, then responsibility to call // ProcessMessage{6,7,Cleanup} has been transferred to InvokeCallback } finally { if (!isBeginSuccessful) { rpc.UnPause(); } } } } finally { try { if (this.parent.SecurityImpersonation != null) { this.parent.SecurityImpersonation.StopImpersonation(ref rpc, impersonationContext, originalPrincipal, isThreadPrincipalSet); } } #pragma warning suppress 56500 // covered by FxCOP catch { string message = null; try { message = SR.GetString(SR.SFxRevertImpersonationFailed0); } finally { DiagnosticUtility.FailFast(message); } } } if (this.isSynchronous) { this.InspectOutputs(ref rpc); this.SerializeOutputs(ref rpc); } else { if (result == null) { throw TraceUtility.ThrowHelperError(new ArgumentNullException("IOperationInvoker.BeginDispatch"), rpc.Request); } if (rpc.CompletedSynchronously.Value) { // if the async call completed synchronously, then the responsibility to call // ProcessMessage{6,7,Cleanup} still remains on this thread rpc.UnPause(); rpc.AsyncResult = result; } } } #pragma warning suppress 56500 // covered by FxCOP catch { throw; } // Make sure user Exception filters are not impersonated. finally { this.UninitializeCallContext(ref rpc); } } } static void InvokeCallback(IAsyncResult result) { IResumeMessageRpc resume = result.AsyncState as IResumeMessageRpc; if (resume == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxInvalidAsyncResultState0)); } if (ImmutableDispatchRuntime.processMessage5IsOnTheStack == resume.AsyncOperationWaitEvent) { // If TLS is marked with the object associated with the current MessageRpc, then we know that // the async operation completed sync. Note this, and then return, so as to unwind the stack // back down to ProcessMessage5, which will finish processing this MessageRpc. resume.SetCompletedSynchronously(); return; } else { // This thread is responsible for the rest of the processing of this MessageRpc. resume.Resume(result); } } ////// Critical - calls SecurityCritical method StartImpersonation /// Safe - manages the result of impersonation and properly Disposes it /// [DebuggerStepperBoundary] [SecurityCritical, SecurityTreatAsSafe] internal void InvokeEnd(ref MessageRpc rpc) { if ((rpc.Error == null) && !this.isSynchronous) { try { this.InitializeCallContext(ref rpc); IDisposable impersonationContext = null; IPrincipal originalPrincipal = null; bool isThreadPrincipalSet = false; try { if (this.parent.SecurityImpersonation != null) { this.parent.SecurityImpersonation.StartImpersonation(ref rpc, out impersonationContext, out originalPrincipal, out isThreadPrincipalSet); } rpc.ReturnParameter = this.Invoker.InvokeEnd(rpc.Instance, out rpc.OutputParameters, rpc.AsyncResult); } finally { try { if (this.parent.SecurityImpersonation != null) { this.parent.SecurityImpersonation.StopImpersonation(ref rpc, impersonationContext, originalPrincipal, isThreadPrincipalSet); } } #pragma warning suppress 56500 // covered by FxCOP catch { string message = null; try { message = SR.GetString(SR.SFxRevertImpersonationFailed0); } finally { DiagnosticUtility.FailFast(message); } } } this.InspectOutputs(ref rpc); this.SerializeOutputs(ref rpc); } #pragma warning suppress 56500 // covered by FxCOP catch { throw; } // Make sure user Exception filters are not impersonated. finally { this.UninitializeCallContext(ref rpc); } } } void SerializeOutputs(ref MessageRpc rpc) { if (!this.IsOneWay && this.parent.EnableFaults) { Message reply; if (this.serializeReply) { try { reply = this.Formatter.SerializeReply(rpc.RequestVersion, rpc.OutputParameters, rpc.ReturnParameter); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } if (ErrorBehavior.ShouldRethrowExceptionAsIs(e)) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } if (reply == null) { string message = SR.GetString(SR.SFxNullReplyFromFormatter2, this.Formatter.GetType().ToString(), (this.name ?? "")); ErrorBehavior.ThrowAndCatch(new InvalidOperationException(message)); } } else { if ((rpc.ReturnParameter == null) && (rpc.OperationContext.RequestContext != null)) { string message = SR.GetString(SR.SFxDispatchRuntimeMessageCannotBeNull, this.name); ErrorBehavior.ThrowAndCatch(new InvalidOperationException(message)); } reply = (Message)rpc.ReturnParameter; if ((reply != null) && (!ProxyOperationRuntime.IsValidAction(reply, this.ReplyAction))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidReplyAction, this.Name, reply.Headers.Action ?? "{NULL}", this.ReplyAction))); } } if (DiagnosticUtility.ShouldUseActivity && rpc.Activity != null && reply != null) { TraceUtility.SetActivity(reply, rpc.Activity); if (TraceUtility.ShouldPropagateActivity) { TraceUtility.AddActivityHeader(reply); } } else if (TraceUtility.ShouldPropagateActivity && reply != null && rpc.ResponseActivityId != Guid.Empty) { ActivityIdHeader header = new ActivityIdHeader(rpc.ResponseActivityId); header.AddTo(reply); } if (MessageLogger.LoggingEnabled && null != reply) { MessageLogger.LogMessage(ref reply, MessageLoggingSource.ServiceLevelSendReply | MessageLoggingSource.LastChance); } rpc.Reply = reply; } } void ValidateInstanceType(Type type, MethodInfo method) { if (!method.DeclaringType.IsAssignableFrom(type)) { string message = SR.GetString(SR.SFxMethodNotSupportedByType2, type.FullName, method.DeclaringType.FullName); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(message)); } } void ValidateMustUnderstand(ref MessageRpc rpc) { if (parent.ValidateMustUnderstand) { rpc.NotUnderstoodHeaders = rpc.Request.Headers.GetHeadersNotUnderstood(); if (rpc.NotUnderstoodHeaders != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new MustUnderstandSoapException(rpc.NotUnderstoodHeaders, rpc.Request.Version.Envelope)); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PolygonHotSpot.cs
- ConnectivityStatus.cs
- SystemException.cs
- QueryInterceptorAttribute.cs
- SqlDataSourceFilteringEventArgs.cs
- URI.cs
- AllMembershipCondition.cs
- PointIndependentAnimationStorage.cs
- IdnElement.cs
- OleDbCommand.cs
- XmlNullResolver.cs
- RangeBase.cs
- SpellerError.cs
- PassportAuthenticationModule.cs
- SystemDiagnosticsSection.cs
- StringFreezingAttribute.cs
- ColorAnimationBase.cs
- SqlDataSourceFilteringEventArgs.cs
- SafeProcessHandle.cs
- XmlWriterSettings.cs
- ValueTypeFixupInfo.cs
- HttpListenerRequest.cs
- EditModeSwitchButton.cs
- DbTransaction.cs
- DataGridViewAdvancedBorderStyle.cs
- XmlSchemaNotation.cs
- AttributeCollection.cs
- InfoCardProofToken.cs
- EventLogWatcher.cs
- OracleRowUpdatingEventArgs.cs
- URL.cs
- XmlTextAttribute.cs
- EventsTab.cs
- AnimatedTypeHelpers.cs
- TypeSystem.cs
- SqlCrossApplyToCrossJoin.cs
- WebMethodAttribute.cs
- TextAdaptor.cs
- ScriptReferenceBase.cs
- ToolStripContainer.cs
- TableParagraph.cs
- SqlTrackingQuery.cs
- BindingBase.cs
- IssuerInformation.cs
- EmptyEnumerable.cs
- PolyLineSegment.cs
- StaticResourceExtension.cs
- WebAdminConfigurationHelper.cs
- IsolatedStorageFileStream.cs
- BuildProvider.cs
- WizardPanel.cs
- UInt64.cs
- SchemaImporterExtension.cs
- WebBrowserContainer.cs
- RijndaelManagedTransform.cs
- DocumentViewerHelper.cs
- DynamicValueConverter.cs
- PathSegmentCollection.cs
- PeerObject.cs
- DrawTreeNodeEventArgs.cs
- Popup.cs
- TargetInvocationException.cs
- CallContext.cs
- EmulateRecognizeCompletedEventArgs.cs
- SqlXml.cs
- JsonFormatReaderGenerator.cs
- ContentFileHelper.cs
- ClientSideProviderDescription.cs
- HijriCalendar.cs
- HttpWriter.cs
- IDQuery.cs
- DesignerUtility.cs
- XmlSchemaAnnotation.cs
- OdbcConnectionHandle.cs
- UnionCodeGroup.cs
- StrokeCollectionConverter.cs
- DocumentApplicationJournalEntryEventArgs.cs
- BinarySecretSecurityToken.cs
- BaseTemplateParser.cs
- cookie.cs
- RemotingServices.cs
- ConnectionsZoneDesigner.cs
- WebResourceAttribute.cs
- MediaCommands.cs
- TextOutput.cs
- SuppressIldasmAttribute.cs
- GenericIdentity.cs
- HorizontalAlignConverter.cs
- Span.cs
- SettingsContext.cs
- WebPartDisplayModeCancelEventArgs.cs
- TypeDependencyAttribute.cs
- TransportListener.cs
- ConfigurationUtility.cs
- ArrayEditor.cs
- StrokeIntersection.cs
- ParseHttpDate.cs
- PackWebRequest.cs
- SocketAddress.cs
- ResourceContainer.cs