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
- ColorTransform.cs
- XPathParser.cs
- AssemblyHash.cs
- TraceHelpers.cs
- SqlLiftIndependentRowExpressions.cs
- DiscoveryDefaults.cs
- DataBinding.cs
- Int32CAMarshaler.cs
- StringBuilder.cs
- ProviderUtil.cs
- TypedTableBase.cs
- FastEncoder.cs
- CommonObjectSecurity.cs
- CompilerTypeWithParams.cs
- VideoDrawing.cs
- WebPartTransformerCollection.cs
- XPathBuilder.cs
- DocumentApplicationState.cs
- odbcmetadatafactory.cs
- OrthographicCamera.cs
- ProgressChangedEventArgs.cs
- RequestBringIntoViewEventArgs.cs
- SecurityContext.cs
- TypeNameHelper.cs
- XsdSchemaFileEditor.cs
- CodeAttributeDeclaration.cs
- DataKeyCollection.cs
- DocumentXPathNavigator.cs
- RowUpdatingEventArgs.cs
- SafeMarshalContext.cs
- DoubleStorage.cs
- TracingConnectionInitiator.cs
- DesigntimeLicenseContextSerializer.cs
- AutomationPropertyInfo.cs
- AvTraceFormat.cs
- X509CertificateStore.cs
- HwndSourceKeyboardInputSite.cs
- PolyLineSegment.cs
- MobileComponentEditorPage.cs
- FileLevelControlBuilderAttribute.cs
- TreeIterator.cs
- EndPoint.cs
- PeerEndPoint.cs
- BaseProcessProtocolHandler.cs
- ResourceDefaultValueAttribute.cs
- WebRequest.cs
- DragEvent.cs
- GridProviderWrapper.cs
- Blend.cs
- SoapProcessingBehavior.cs
- ApplicationServiceHelper.cs
- ColumnMapCopier.cs
- MetadataItemEmitter.cs
- TemplatedWizardStep.cs
- XmlReader.cs
- CFStream.cs
- Base64Encoder.cs
- StylusPointDescription.cs
- MediaSystem.cs
- DynamicArgumentDialog.cs
- DependencyPropertyValueSerializer.cs
- SimpleHandlerBuildProvider.cs
- manifestimages.cs
- StylusTip.cs
- PolicyManager.cs
- SegmentTree.cs
- RegistrySecurity.cs
- GeneralTransform3DTo2DTo3D.cs
- MoveSizeWinEventHandler.cs
- SchemaElementDecl.cs
- WindowsUserNameSecurityTokenAuthenticator.cs
- GuidConverter.cs
- AsyncOperationLifetimeManager.cs
- UserPersonalizationStateInfo.cs
- TempFiles.cs
- SystemTcpStatistics.cs
- TypeConverterHelper.cs
- SingleQueryOperator.cs
- ZipPackage.cs
- HideDisabledControlAdapter.cs
- CustomAttributeSerializer.cs
- ZipPackagePart.cs
- PrintPreviewDialog.cs
- StoreContentChangedEventArgs.cs
- ColumnClickEvent.cs
- TextElementEditingBehaviorAttribute.cs
- EntityClientCacheEntry.cs
- CodeGenerator.cs
- AggregationMinMaxHelpers.cs
- RequiredAttributeAttribute.cs
- WindowsFormsSectionHandler.cs
- TextTrailingCharacterEllipsis.cs
- Help.cs
- GuidConverter.cs
- ProgressBar.cs
- GridViewRowPresenter.cs
- DefaultValidator.cs
- User.cs
- DocumentGridContextMenu.cs
- APCustomTypeDescriptor.cs