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
- ElementsClipboardData.cs
- SocketAddress.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- CheckBoxField.cs
- RecordConverter.cs
- StylusDownEventArgs.cs
- Geometry.cs
- TableRow.cs
- SoapReflectionImporter.cs
- WmlControlAdapter.cs
- FormViewDeleteEventArgs.cs
- InputBindingCollection.cs
- XmlByteStreamWriter.cs
- CommunicationObjectFaultedException.cs
- SettingsPropertyCollection.cs
- BitmapEffectGroup.cs
- ChannelBinding.cs
- SecurityElement.cs
- UnlockInstanceAsyncResult.cs
- PropertyEmitter.cs
- AppSettingsSection.cs
- BulletChrome.cs
- SafeIUnknown.cs
- XmlEnumAttribute.cs
- SynchronizedDispatch.cs
- DataGridHeaderBorder.cs
- GeneralTransform3DGroup.cs
- QuinticEase.cs
- WebPartUtil.cs
- PeerInvitationResponse.cs
- BitmapDownload.cs
- StringStorage.cs
- CancelEventArgs.cs
- DBSqlParserColumn.cs
- BitVec.cs
- ErrorWrapper.cs
- BaseValidator.cs
- CorrelationInitializer.cs
- WebPartMinimizeVerb.cs
- XmlCharType.cs
- ApplyTemplatesAction.cs
- AutomationPatternInfo.cs
- ObjectAnimationUsingKeyFrames.cs
- DbProviderFactoriesConfigurationHandler.cs
- WinFormsSecurity.cs
- TemplateBamlTreeBuilder.cs
- RepeatButton.cs
- VBIdentifierName.cs
- SafeCertificateStore.cs
- TextElementEditingBehaviorAttribute.cs
- Expression.cs
- ObjectStateEntryDbDataRecord.cs
- SkipStoryboardToFill.cs
- HttpModuleActionCollection.cs
- SqlMultiplexer.cs
- NameSpaceEvent.cs
- DataGridCell.cs
- RichTextBox.cs
- DataServiceConfiguration.cs
- EventsTab.cs
- WebUtility.cs
- UserNamePasswordValidator.cs
- SemaphoreSlim.cs
- CheckableControlBaseAdapter.cs
- UserControlCodeDomTreeGenerator.cs
- _LocalDataStoreMgr.cs
- CodeTypeMember.cs
- CodeTypeDeclarationCollection.cs
- XmlSerializationReader.cs
- MetadataUtilsSmi.cs
- GroupQuery.cs
- metadatamappinghashervisitor.cs
- TextSearch.cs
- TextTabProperties.cs
- IriParsingElement.cs
- TranslateTransform.cs
- ScaleTransform.cs
- WorkflowItemsPresenter.cs
- SoapObjectReader.cs
- AsyncOperationManager.cs
- CompressEmulationStream.cs
- DataPagerFieldCommandEventArgs.cs
- PropertyItemInternal.cs
- RedistVersionInfo.cs
- DataControlButton.cs
- PerformanceCounterLib.cs
- DeclarativeCatalogPart.cs
- HeaderCollection.cs
- XmlQueryRuntime.cs
- LineServicesRun.cs
- CodeCompileUnit.cs
- WindowsStartMenu.cs
- CodeDOMUtility.cs
- SessionParameter.cs
- XmlDomTextWriter.cs
- ContextQuery.cs
- CheckedPointers.cs
- TextReader.cs
- EntityAdapter.cs
- HtmlInputControl.cs