Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / TransactionValidationBehavior.cs / 1 / TransactionValidationBehavior.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System.Collections.ObjectModel; using System.ServiceModel.Channels; using System.ServiceModel; using System.ServiceModel.Description; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.ServiceModel.Transactions; class TransactionValidationBehavior : IEndpointBehavior, IServiceBehavior { static TransactionValidationBehavior instance; internal static TransactionValidationBehavior Instance { get { if (instance == null) instance = new TransactionValidationBehavior(); return instance; } } TransactionValidationBehavior() {} void ValidateTransactionFlowRequired(string resource, string name, ServiceEndpoint endpoint) { bool anOperationRequiresTxFlow = false; for (int i = 0; i < endpoint.Contract.Operations.Count; i++) { OperationDescription operationDescription = endpoint.Contract.Operations[i]; TransactionFlowAttribute transactionFlow = operationDescription.Behaviors.Find(); if (transactionFlow != null && transactionFlow.Transactions == TransactionFlowOption.Mandatory) { anOperationRequiresTxFlow = true; break; } } if (anOperationRequiresTxFlow) { CustomBinding binding = new CustomBinding(endpoint.Binding); TransactionFlowBindingElement transactionFlowBindingElement = binding.Elements.Find (); if (transactionFlowBindingElement == null || !transactionFlowBindingElement.Transactions) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( String.Format(Globalization.CultureInfo.CurrentCulture, SR.GetString(resource), name, binding.Name))); } } } void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint) { if (serviceEndpoint == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceEndpoint"); ValidateTransactionFlowRequired(SR.ChannelHasAtLeastOneOperationWithTransactionFlowEnabled, serviceEndpoint.Contract.Name, serviceEndpoint); EnsureNoOneWayTransactions(serviceEndpoint); ValidateNoMSMQandTransactionFlow(serviceEndpoint); ValidateCallbackBehaviorAttributeWithNoScopeRequired(serviceEndpoint); OperationDescription autoCompleteFalseOperation = GetAutoCompleteFalseOperation(serviceEndpoint); if(autoCompleteFalseOperation != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionAutoCompleteFalseOnCallbackContract, autoCompleteFalseOperation.Name, serviceEndpoint.Contract.Name))); } } void ValidateCallbackBehaviorAttributeWithNoScopeRequired(ServiceEndpoint endpoint) { // If the endpoint has no operations with TransactionScopeRequired=true, disallow any // transaction-related properties on the CallbackBehaviorAttribute if (!HasTransactedOperations(endpoint)) { CallbackBehaviorAttribute attribute = endpoint.Behaviors.Find (); if (attribute != null) { if (attribute.TransactionTimeoutSet) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionTransactionTimeoutNeedsScope, endpoint.Contract.Name))); } if (attribute.IsolationLevelSet) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionIsolationLevelNeedsScope, endpoint.Contract.Name))); } } } } void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters) { } void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { } void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior) { } void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection parameters) { } void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription service, ServiceHostBase serviceHostBase) { } void IServiceBehavior.Validate(ServiceDescription service, ServiceHostBase serviceHostBase) { if (service == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("service"); ValidateNotConcurrentWhenReleaseServiceInstanceOnTxComplete(service); bool singleThreaded = IsSingleThreaded(service); for (int i = 0; i < service.Endpoints.Count; i++) { ServiceEndpoint endpoint = service.Endpoints[i]; ValidateTransactionFlowRequired(SR.ServiceHasAtLeastOneOperationWithTransactionFlowEnabled, service.Name, endpoint); EnsureNoOneWayTransactions(endpoint); ValidateNoMSMQandTransactionFlow(endpoint); ContractDescription contract = endpoint.Contract; for (int j = 0; j < contract.Operations.Count; j++) { OperationDescription operation = contract.Operations[j]; ValidateScopeRequiredAndAutoComplete(operation, singleThreaded, contract.Name); } ValidateAutoCompleteFalseRequirements(service, endpoint); } ValidateServiceBehaviorAttributeWithNoScopeRequired(service); ValidateTransactionAutoCompleteOnSessionCloseHasSession(service); } void ValidateAutoCompleteFalseRequirements(ServiceDescription service, ServiceEndpoint endpoint) { OperationDescription autoCompleteFalseOperation = GetAutoCompleteFalseOperation(endpoint); if (autoCompleteFalseOperation != null) { // Does the service have InstanceContextMode.PerSession or Shareable? ServiceBehaviorAttribute serviceBehavior = service.Behaviors.Find (); if (serviceBehavior != null) { InstanceContextMode instanceMode = serviceBehavior.InstanceContextMode; if (instanceMode != InstanceContextMode.PerSession) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionAutoCompleteFalseAndInstanceContextMode, endpoint.Contract.Name, autoCompleteFalseOperation.Name))); } } // Does the binding support sessions? if (!RequiresSessions(endpoint)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionAutoCompleteFalseAndSupportsSession, endpoint.Contract.Name, autoCompleteFalseOperation.Name))); } } } OperationDescription GetAutoCompleteFalseOperation(ServiceEndpoint endpoint) { foreach (OperationDescription operation in endpoint.Contract.Operations) { if (!IsAutoComplete(operation)) { return operation; } } return null; } void ValidateTransactionAutoCompleteOnSessionCloseHasSession(ServiceDescription service) { ServiceBehaviorAttribute serviceBehavior = service.Behaviors.Find (); if (serviceBehavior != null) { InstanceContextMode instanceMode = serviceBehavior.InstanceContextMode; if (serviceBehavior.TransactionAutoCompleteOnSessionClose&& instanceMode != InstanceContextMode.PerSession) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionAutoCompleteOnSessionCloseNoSession, service.Name))); } } } void ValidateServiceBehaviorAttributeWithNoScopeRequired(ServiceDescription service) { // If the service has no operations with TransactionScopeRequired=true, disallow any // transaction-related properties on the ServiceBehaviorAttribute if (!HasTransactedOperations(service)) { ServiceBehaviorAttribute attribute = service.Behaviors.Find (); if (attribute != null) { if (attribute.TransactionTimeoutSet) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionTransactionTimeoutNeedsScope, service.Name))); } if (attribute.IsolationLevelSet) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionIsolationLevelNeedsScope, service.Name))); } if (attribute.ReleaseServiceInstanceOnTransactionCompleteSet) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionReleaseServiceInstanceOnTransactionCompleteNeedsScope, service.Name))); } if (attribute.TransactionAutoCompleteOnSessionCloseSet) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionTransactionAutoCompleteOnSessionCloseNeedsScope, service.Name))); } } } } void EnsureNoOneWayTransactions(ServiceEndpoint endpoint) { CustomBinding binding = new CustomBinding(endpoint.Binding); TransactionFlowBindingElement txFlowBindingElement = binding.Elements.Find (); if (txFlowBindingElement != null) { for (int i = 0; i < endpoint.Contract.Operations.Count; i++) { OperationDescription operation = endpoint.Contract.Operations[i]; if (operation.IsOneWay) { TransactionFlowAttribute tfbp = operation.Behaviors.Find (); TransactionFlowOption transactions; if (tfbp != null) { transactions = tfbp.Transactions; } else { transactions = TransactionFlowOption.NotAllowed; } if (TransactionFlowOptionHelper.AllowedOrRequired(transactions)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxOneWayAndTransactionsIncompatible, endpoint.Contract.Name, operation.Name))); } } } } } bool HasTransactedOperations(ServiceDescription service) { for (int i = 0; i < service.Endpoints.Count; i++) { if(HasTransactedOperations(service.Endpoints[i])) { return true; } } return false; } bool HasTransactedOperations(ServiceEndpoint endpoint) { for (int j = 0; j < endpoint.Contract.Operations.Count; j++) { OperationDescription operation = endpoint.Contract.Operations[j]; OperationBehaviorAttribute attribute = operation.Behaviors.Find (); if (attribute != null && attribute.TransactionScopeRequired) { return true; } } return false; } bool IsSingleThreaded(ServiceDescription service) { ServiceBehaviorAttribute attribute = service.Behaviors.Find (); if (attribute != null) { return (attribute.ConcurrencyMode == ConcurrencyMode.Single); } // The default is ConcurrencyMode.Single return true; } bool IsAutoComplete(OperationDescription operation) { OperationBehaviorAttribute attribute = operation.Behaviors.Find (); if (attribute != null) { return attribute.TransactionAutoComplete; } // The default is TransactionAutoComplete=true return true; } bool RequiresSessions(ServiceEndpoint endpoint) { return endpoint.Contract.SessionMode == SessionMode.Required; } void ValidateScopeRequiredAndAutoComplete(OperationDescription operation, bool singleThreaded, string contractName) { OperationBehaviorAttribute attribute = operation.Behaviors.Find (); if (attribute != null) { if (!attribute.TransactionScopeRequired && !attribute.TransactionAutoComplete) { string id = SR.SFxTransactionAutoEnlistOrAutoComplete2; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(id, contractName, operation.Name))); } if (!singleThreaded && !attribute.TransactionAutoComplete) { string id = SR.SFxTransactionNonConcurrentOrAutoComplete2; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(id, contractName, operation.Name))); } } } void ValidateNoMSMQandTransactionFlow(ServiceEndpoint endpoint) { BindingElementCollection bindingElements = endpoint.Binding.CreateBindingElements(); if(bindingElements.Find () != null && bindingElements.Find () != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxTransactionFlowAndMSMQ, endpoint.Address.Uri.AbsoluteUri))); } } void ValidateNotConcurrentWhenReleaseServiceInstanceOnTxComplete(ServiceDescription service) { ServiceBehaviorAttribute attribute = service.Behaviors.Find (); if (attribute != null && HasTransactedOperations(service)) { if (attribute.ReleaseServiceInstanceOnTransactionComplete && !IsSingleThreaded(service)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR.GetString( SR.SFxTransactionNonConcurrentOrReleaseServiceInstanceOnTxComplete, service.Name))); } } } } } // 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
- XmlDataLoader.cs
- entitydatasourceentitysetnameconverter.cs
- Visual3D.cs
- NTAccount.cs
- XdrBuilder.cs
- Console.cs
- ConstructorNeedsTagAttribute.cs
- PrimarySelectionGlyph.cs
- SortFieldComparer.cs
- ItemsPanelTemplate.cs
- ChannelServices.cs
- UIAgentRequest.cs
- CustomErrorsSectionWrapper.cs
- ImageButton.cs
- AccessViolationException.cs
- DataSourceView.cs
- QueryableDataSourceHelper.cs
- ObfuscateAssemblyAttribute.cs
- SoapEnumAttribute.cs
- Function.cs
- HierarchicalDataSourceControl.cs
- CodeExpressionStatement.cs
- CellPartitioner.cs
- TextWriter.cs
- EntitySqlQueryCacheEntry.cs
- RelationshipEndCollection.cs
- TextBoxDesigner.cs
- PointAnimationUsingKeyFrames.cs
- ResourcePermissionBaseEntry.cs
- NavigationFailedEventArgs.cs
- Rect3DConverter.cs
- ResizeGrip.cs
- BamlRecordReader.cs
- DesignerForm.cs
- ResourcePart.cs
- DbParameterCollection.cs
- SchemaRegistration.cs
- ProviderUtil.cs
- NonDualMessageSecurityOverHttpElement.cs
- ExtendedProtectionPolicy.cs
- XPathDocument.cs
- PresentationSource.cs
- SystemKeyConverter.cs
- BaseDataBoundControl.cs
- HtmlTitle.cs
- SqlClientFactory.cs
- StateValidator.cs
- SettingsPropertyIsReadOnlyException.cs
- PolicyChain.cs
- EventProxy.cs
- QilVisitor.cs
- OleDbException.cs
- OpenFileDialog.cs
- PrincipalPermission.cs
- XmlWrappingWriter.cs
- SortAction.cs
- AddressAlreadyInUseException.cs
- CollectionViewSource.cs
- PagePropertiesChangingEventArgs.cs
- ZoneIdentityPermission.cs
- SourceSwitch.cs
- HttpCookiesSection.cs
- DispatcherHookEventArgs.cs
- DependencyPropertyValueSerializer.cs
- OdbcRowUpdatingEvent.cs
- ReferenceEqualityComparer.cs
- EntityDataSourceValidationException.cs
- ConnectorRouter.cs
- MenuTracker.cs
- KeyPullup.cs
- Avt.cs
- Array.cs
- WindowsClaimSet.cs
- UntypedNullExpression.cs
- PropertyFilterAttribute.cs
- WebException.cs
- MemberAccessException.cs
- SubMenuStyleCollection.cs
- ListViewGroupCollectionEditor.cs
- FilteredReadOnlyMetadataCollection.cs
- TrustSection.cs
- EastAsianLunisolarCalendar.cs
- ContextStack.cs
- TextServicesCompartment.cs
- BinaryConverter.cs
- CodeTypeReferenceCollection.cs
- RefreshEventArgs.cs
- TypeUtils.cs
- EventLogPermissionEntry.cs
- ScopedKnownTypes.cs
- SignatureDescription.cs
- MappingModelBuildProvider.cs
- Context.cs
- PropertyChangingEventArgs.cs
- SqlHelper.cs
- ErrorHandler.cs
- TextTreeRootNode.cs
- ActivityXRefPropertyEditor.cs
- FtpRequestCacheValidator.cs
- InvokePattern.cs