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
- GroupItem.cs
- DefaultSection.cs
- AssemblyInfo.cs
- DataObjectEventArgs.cs
- HostingEnvironmentException.cs
- Symbol.cs
- PermissionSet.cs
- MetadataUtil.cs
- DesignerTextWriter.cs
- ParameterInfo.cs
- StructureChangedEventArgs.cs
- EtwTrace.cs
- MatcherBuilder.cs
- StrongNameUtility.cs
- LinqDataSourceDisposeEventArgs.cs
- PageSettings.cs
- SerialPinChanges.cs
- InternalConfigEventArgs.cs
- CodeGenerator.cs
- MeasureItemEvent.cs
- brushes.cs
- AppSettingsExpressionBuilder.cs
- PageBuildProvider.cs
- DataBoundControlHelper.cs
- Win32PrintDialog.cs
- QilFunction.cs
- Grant.cs
- SlotInfo.cs
- NamedPipeAppDomainProtocolHandler.cs
- FlowLayoutSettings.cs
- DataDesignUtil.cs
- CounterCreationDataCollection.cs
- ArglessEventHandlerProxy.cs
- baseaxisquery.cs
- DataControlCommands.cs
- CharEnumerator.cs
- Material.cs
- SafeRightsManagementPubHandle.cs
- FrugalList.cs
- Input.cs
- Shared.cs
- TabControlCancelEvent.cs
- CollectionViewGroup.cs
- UriTemplatePathSegment.cs
- ServiceControllerDesigner.cs
- RubberbandSelector.cs
- CodeStatementCollection.cs
- InternalConfigRoot.cs
- DataGridRowEventArgs.cs
- RequestQueue.cs
- PropertyChangedEventArgs.cs
- WebAdminConfigurationHelper.cs
- HtmlButton.cs
- TextMetrics.cs
- TaiwanLunisolarCalendar.cs
- X509SecurityTokenAuthenticator.cs
- TreeChangeInfo.cs
- BitmapSizeOptions.cs
- XsltQilFactory.cs
- CloseSequenceResponse.cs
- WebUtil.cs
- DataGridClipboardCellContent.cs
- ClockGroup.cs
- XmlIterators.cs
- RbTree.cs
- Point3D.cs
- StoreContentChangedEventArgs.cs
- DeflateEmulationStream.cs
- LogReservationCollection.cs
- Helper.cs
- JavaScriptString.cs
- ObjectTypeMapping.cs
- RewritingSimplifier.cs
- LinqDataSource.cs
- XmlUTF8TextWriter.cs
- basevalidator.cs
- DbConnectionFactory.cs
- LinqDataSource.cs
- SystemParameters.cs
- HMACSHA384.cs
- StaticSiteMapProvider.cs
- Misc.cs
- QilSortKey.cs
- CapabilitiesPattern.cs
- MeasurementDCInfo.cs
- XmlDictionaryReaderQuotas.cs
- cookieexception.cs
- SqlDataSourceCache.cs
- Events.cs
- MessageBox.cs
- DependencyProperty.cs
- BatchStream.cs
- GeneralTransform3D.cs
- TreeViewItemAutomationPeer.cs
- ScrollChangedEventArgs.cs
- NotifyCollectionChangedEventArgs.cs
- RootProfilePropertySettingsCollection.cs
- TerminatorSinks.cs
- XmlILOptimizerVisitor.cs
- ProcessModuleCollection.cs