1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Description
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.Collections.ObjectModel;
9 using System.Globalization;
11 using System.Security;
12 using System.ServiceModel;
13 using System.ServiceModel.Channels;
16 using System.Xml.Schema;
17 using ConfigNS = System.ServiceModel.Configuration;
18 using WsdlConfigNS = System.Web.Services.Configuration;
19 using WsdlNS = System.Web.Services.Description;
21 public class WsdlImporter : MetadataImporter
23 readonly Dictionary<WsdlNS.NamedItem, WsdlImportException> importErrors = new Dictionary<WsdlNS.NamedItem, WsdlImportException>();
24 bool isFaulted = false;
26 readonly Dictionary<XmlQualifiedName, WsdlContractConversionContext> importedPortTypes = new Dictionary<XmlQualifiedName, WsdlContractConversionContext>();
27 readonly Dictionary<XmlQualifiedName, WsdlEndpointConversionContext> importedBindings = new Dictionary<XmlQualifiedName, WsdlEndpointConversionContext>();
28 readonly Dictionary<WsdlNS.Port, ServiceEndpoint> importedPorts = new Dictionary<WsdlNS.Port, ServiceEndpoint>();
30 readonly KeyedByTypeCollection<IWsdlImportExtension> wsdlExtensions;
32 readonly WsdlNS.ServiceDescriptionCollection wsdlDocuments = new WsdlNS.ServiceDescriptionCollection();
33 readonly XmlSchemaSet xmlSchemas = WsdlExporter.GetEmptySchemaSet();
34 readonly Dictionary<string, XmlElement> policyDocuments = new Dictionary<string, XmlElement>();
35 readonly Dictionary<string, string> warnings = new Dictionary<string, string>();
36 WsdlPolicyReader wsdlPolicyReader;
38 bool beforeImportCalled = false;
40 public WsdlImporter(MetadataSet metadata)
41 : this(metadata, null, null, MetadataImporterQuotas.Defaults)
45 public WsdlImporter(MetadataSet metadata, IEnumerable<IPolicyImportExtension> policyImportExtensions,
46 IEnumerable<IWsdlImportExtension> wsdlImportExtensions)
47 : this(metadata, policyImportExtensions, wsdlImportExtensions, MetadataImporterQuotas.Defaults)
51 public WsdlImporter(MetadataSet metadata, IEnumerable<IPolicyImportExtension> policyImportExtensions,
52 IEnumerable<IWsdlImportExtension> wsdlImportExtensions, MetadataImporterQuotas quotas)
53 : base(policyImportExtensions, quotas)
55 // process wsdl extensions first for consistency with policy extensions (which are processed in base ctor)
56 if (wsdlImportExtensions == null)
58 wsdlImportExtensions = LoadWsdlExtensionsFromConfig();
61 this.wsdlExtensions = new KeyedByTypeCollection<IWsdlImportExtension>(wsdlImportExtensions);
63 // then look at metadata
65 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("metadata");
67 this.ProcessMetadataDocuments(metadata.MetadataSections);
70 public KeyedByTypeCollection<IWsdlImportExtension> WsdlImportExtensions
72 get { return this.wsdlExtensions; }
75 public WsdlNS.ServiceDescriptionCollection WsdlDocuments
77 get { return this.wsdlDocuments; }
80 public XmlSchemaSet XmlSchemas
82 get { return this.xmlSchemas; }
85 WsdlPolicyReader PolicyReader
89 if (this.wsdlPolicyReader == null)
91 this.wsdlPolicyReader = new WsdlPolicyReader(this);
93 return wsdlPolicyReader;
97 //Consider this should be made public
98 internal override XmlElement ResolvePolicyReference(string policyReference, XmlElement contextAssertion)
100 return this.PolicyReader.ResolvePolicyReference(policyReference, contextAssertion);
103 public override Collection<ContractDescription> ImportAllContracts()
106 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
108 EnsureBeforeImportCalled();
109 Collection<ContractDescription> contracts = new Collection<ContractDescription>();
110 foreach (WsdlNS.ServiceDescription wsdl in this.wsdlDocuments)
111 foreach (WsdlNS.PortType wsdlPortType in wsdl.PortTypes)
113 if (IsBlackListed(wsdlPortType))
116 ContractDescription contract = ImportWsdlPortType(wsdlPortType, WsdlPortTypeImportOptions.ReuseExistingContracts, ErrorBehavior.DoNotThrowExceptions);
117 if (contract != null)
118 contracts.Add(contract);
123 public override ServiceEndpointCollection ImportAllEndpoints()
126 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
128 EnsureBeforeImportCalled();
129 ServiceEndpointCollection endpoints = new ServiceEndpointCollection();
130 foreach (WsdlNS.Port wsdlPort in this.GetAllPorts())
132 if (IsBlackListed(wsdlPort))
135 ServiceEndpoint endpoint = ImportWsdlPort(wsdlPort, ErrorBehavior.DoNotThrowExceptions);
136 if (endpoint != null)
137 endpoints.Add(endpoint);
142 public Collection<Binding> ImportAllBindings()
145 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
147 EnsureBeforeImportCalled();
148 Collection<Binding> bindings = new Collection<Binding>();
149 foreach (WsdlNS.Binding wsdlBinding in this.GetAllBindings())
151 WsdlEndpointConversionContext importedBindingContext = null;
152 if (IsBlackListed(wsdlBinding))
155 importedBindingContext = ImportWsdlBinding(wsdlBinding, ErrorBehavior.DoNotThrowExceptions);
156 if (importedBindingContext != null)
157 bindings.Add(importedBindingContext.Endpoint.Binding);
162 // WSDL Specific methods
163 public ContractDescription ImportContract(WsdlNS.PortType wsdlPortType)
166 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
168 if (wsdlPortType == null)
169 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wsdlPortType");
171 return ImportWsdlPortType(wsdlPortType, WsdlPortTypeImportOptions.ReuseExistingContracts, ErrorBehavior.RethrowExceptions);
174 public Binding ImportBinding(WsdlNS.Binding wsdlBinding)
177 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
179 if (wsdlBinding == null)
180 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wsdlBinding");
182 return ImportWsdlBinding(wsdlBinding, ErrorBehavior.RethrowExceptions).Endpoint.Binding;
185 public ServiceEndpoint ImportEndpoint(WsdlNS.Port wsdlPort)
188 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
190 if (wsdlPort == null)
191 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wsdlPort");
193 return ImportWsdlPort(wsdlPort, ErrorBehavior.RethrowExceptions);
196 public ServiceEndpointCollection ImportEndpoints(WsdlNS.PortType wsdlPortType)
199 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
201 if (wsdlPortType == null)
202 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wsdlPortType");
204 if (IsBlackListed(wsdlPortType))
205 throw CreateAlreadyFaultedException(wsdlPortType);
207 ImportWsdlPortType(wsdlPortType, WsdlPortTypeImportOptions.ReuseExistingContracts, ErrorBehavior.RethrowExceptions);
209 ServiceEndpointCollection endpoints = new ServiceEndpointCollection();
211 foreach (WsdlNS.Binding wsdlBinding in FindBindingsForPortType(wsdlPortType))
212 if (!IsBlackListed(wsdlBinding))
213 foreach (ServiceEndpoint endpoint in ImportEndpoints(wsdlBinding))
214 endpoints.Add(endpoint);
219 internal ServiceEndpointCollection ImportEndpoints(ContractDescription contract)
222 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
224 if (contract == null)
225 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
227 if (!this.KnownContracts.ContainsKey(WsdlExporter.WsdlNamingHelper.GetPortTypeQName(contract)))
229 Fx.Assert("WsdlImporter.ImportEndpoints(ContractDescription contract): !this.KnownContracts.ContainsKey(WsdlExporter.WsdlNamingHelper.GetPortTypeQName(contract))");
230 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.WsdlImporterContractMustBeInKnownContracts)));
233 EnsureBeforeImportCalled();
234 ServiceEndpointCollection endpoints = new ServiceEndpointCollection();
236 foreach (WsdlNS.Binding wsdlBinding in FindBindingsForContract(contract))
237 if (!IsBlackListed(wsdlBinding))
238 foreach (ServiceEndpoint endpoint in ImportEndpoints(wsdlBinding))
239 endpoints.Add(endpoint);
244 public ServiceEndpointCollection ImportEndpoints(WsdlNS.Binding wsdlBinding)
247 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
249 if (wsdlBinding == null)
250 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wsdlBinding");
252 if (IsBlackListed(wsdlBinding))
253 throw CreateAlreadyFaultedException(wsdlBinding);
255 ImportWsdlBinding(wsdlBinding, ErrorBehavior.RethrowExceptions);
257 ServiceEndpointCollection endpoints = new ServiceEndpointCollection();
259 foreach (WsdlNS.Port wsdlPort in FindPortsForBinding(wsdlBinding))
260 if (!IsBlackListed(wsdlPort))
262 ServiceEndpoint endpoint = ImportWsdlPort(wsdlPort, ErrorBehavior.DoNotThrowExceptions);
263 if (endpoint != null)
264 endpoints.Add(endpoint);
270 public ServiceEndpointCollection ImportEndpoints(WsdlNS.Service wsdlService)
273 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.WsdlImporterIsFaulted)));
275 if (wsdlService == null)
276 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wsdlService");
278 EnsureBeforeImportCalled();
279 ServiceEndpointCollection endpoints = new ServiceEndpointCollection();
281 foreach (WsdlNS.Port wsdlPort in wsdlService.Ports)
282 if (!IsBlackListed(wsdlPort))
284 ServiceEndpoint endpoint = ImportWsdlPort(wsdlPort, ErrorBehavior.DoNotThrowExceptions);
285 if (endpoint != null)
286 endpoints.Add(endpoint);
292 bool IsBlackListed(WsdlNS.NamedItem item)
294 return importErrors.ContainsKey(item);
297 ContractDescription ImportWsdlPortType(WsdlNS.PortType wsdlPortType, WsdlPortTypeImportOptions importOptions, ErrorBehavior errorBehavior)
299 if (IsBlackListed(wsdlPortType))
300 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateAlreadyFaultedException(wsdlPortType));
303 XmlQualifiedName wsdlPortTypeQName = new XmlQualifiedName(wsdlPortType.Name, wsdlPortType.ServiceDescription.TargetNamespace);
304 ContractDescription contractDescription = null;
306 if (importOptions == WsdlPortTypeImportOptions.IgnoreExistingContracts || !TryFindExistingContract(wsdlPortTypeQName, out contractDescription))
308 EnsureBeforeImportCalled();
313 contractDescription = CreateContractDescription(wsdlPortType, wsdlPortTypeQName);
314 WsdlContractConversionContext contractContext = new WsdlContractConversionContext(contractDescription, wsdlPortType);
316 foreach (WsdlNS.Operation wsdlOperation in wsdlPortType.Operations)
319 OperationDescription operationDescription = CreateOperationDescription(wsdlPortType, wsdlOperation, contractDescription);
320 contractContext.AddOperation(operationDescription, wsdlOperation);
322 foreach (WsdlNS.OperationMessage wsdlOperationMessage in wsdlOperation.Messages)
324 MessageDescription messageDescription;
325 if (TryCreateMessageDescription(wsdlOperationMessage, operationDescription, out messageDescription))
326 contractContext.AddMessage(messageDescription, wsdlOperationMessage);
329 foreach (WsdlNS.OperationFault wsdlOperationFault in wsdlOperation.Faults)
331 FaultDescription faultDescription;
332 if (TryCreateFaultDescription(wsdlOperationFault, operationDescription, out faultDescription))
333 contractContext.AddFault(faultDescription, wsdlOperationFault);
337 CallImportContract(contractContext);
338 VerifyImportedWsdlPortType(wsdlPortType);
340 importedPortTypes.Add(wsdlPortTypeQName, contractContext);
342 #pragma warning suppress 56500 // covered by FxCOP
347 WsdlImportException wie = WsdlImportException.Create(wsdlPortType, e);
348 LogImportError(wsdlPortType, wie);
349 if (errorBehavior == ErrorBehavior.RethrowExceptions)
350 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(wie);
356 return contractDescription;
359 WsdlEndpointConversionContext ImportWsdlBinding(WsdlNS.Binding wsdlBinding, ErrorBehavior errorBehavior)
361 //Check for exisiting exception
362 if (IsBlackListed(wsdlBinding))
363 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateAlreadyFaultedException(wsdlBinding));
365 XmlQualifiedName wsdlBindingQName = new XmlQualifiedName(wsdlBinding.Name, wsdlBinding.ServiceDescription.TargetNamespace);
366 WsdlEndpointConversionContext bindingEndpointContext = null;
371 if (!importedBindings.TryGetValue(wsdlBindingQName, out bindingEndpointContext))
373 EnsureBeforeImportCalled();
377 bool wasExistingContract;
378 ContractDescription contractDescription = GetOrImportContractDescription(wsdlBinding.Type, out wasExistingContract);
379 WsdlContractConversionContext contractContext = null;
380 importedPortTypes.TryGetValue(wsdlBinding.Type, out contractContext);
382 ServiceEndpoint newWsdlBindingEndpoint = new ServiceEndpoint(contractDescription);
383 bindingEndpointContext = new WsdlEndpointConversionContext(contractContext, newWsdlBindingEndpoint, wsdlBinding, null);
385 foreach (WsdlNS.OperationBinding wsdlOperationBinding in wsdlBinding.Operations)
388 OperationDescription operation = Binding2DescriptionHelper.FindOperationDescription(wsdlOperationBinding, wsdlDocuments, bindingEndpointContext);
389 bindingEndpointContext.AddOperationBinding(operation, wsdlOperationBinding);
391 for (int i = 0; i < operation.Messages.Count; i++)
393 MessageDescription message = operation.Messages[i];
394 WsdlNS.MessageBinding wsdlMessageBinding = Binding2DescriptionHelper.FindMessageBinding(wsdlOperationBinding, message);
396 bindingEndpointContext.AddMessageBinding(message, wsdlMessageBinding);
399 foreach (FaultDescription fault in operation.Faults)
401 WsdlNS.FaultBinding wsdlFaultBinding = Binding2DescriptionHelper.FindFaultBinding(wsdlOperationBinding, fault);
402 if (wsdlFaultBinding != null)
404 bindingEndpointContext.AddFaultBinding(fault, wsdlFaultBinding);
408 #pragma warning suppress 56500 // covered by FxCOP
413 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(wsdlOperationBinding, e));
416 XmlQualifiedName bindingQName = WsdlNamingHelper.GetBindingName(wsdlBinding);
417 newWsdlBindingEndpoint.Binding = CreateBinding(bindingEndpointContext, bindingQName);
419 CallImportEndpoint(bindingEndpointContext);
420 VerifyImportedWsdlBinding(wsdlBinding);
421 importedBindings.Add(wsdlBindingQName, bindingEndpointContext);
423 #pragma warning suppress 56500 // covered by FxCOP
428 WsdlImportException wie = WsdlImportException.Create(wsdlBinding, e);
429 LogImportError(wsdlBinding, wie);
430 if (errorBehavior == ErrorBehavior.RethrowExceptions)
431 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(wie);
436 return bindingEndpointContext;
439 ServiceEndpoint ImportWsdlPort(WsdlNS.Port wsdlPort, ErrorBehavior errorBehavior)
441 if (IsBlackListed(wsdlPort))
442 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateAlreadyFaultedException(wsdlPort));
445 ServiceEndpoint endpoint = null;
446 if (!importedPorts.TryGetValue(wsdlPort, out endpoint))
448 EnsureBeforeImportCalled();
452 WsdlNS.Binding wsdlBinding = this.wsdlDocuments.GetBinding(wsdlPort.Binding);
454 WsdlEndpointConversionContext bindingEndpointContext = ImportWsdlBinding(wsdlBinding, ErrorBehavior.RethrowExceptions);
456 WsdlEndpointConversionContext endpointContext;
457 endpoint = new ServiceEndpoint(bindingEndpointContext.Endpoint.Contract);
458 endpoint.Name = WsdlNamingHelper.GetEndpointName(wsdlPort).EncodedName;
460 endpointContext = new WsdlEndpointConversionContext(bindingEndpointContext, endpoint, wsdlPort);
462 if (WsdlPolicyReader.HasPolicy(wsdlPort))
464 XmlQualifiedName bindingQName = WsdlNamingHelper.GetBindingName(wsdlPort);
465 endpoint.Binding = CreateBinding(endpointContext, bindingQName);
469 endpoint.Binding = bindingEndpointContext.Endpoint.Binding;
472 CallImportEndpoint(endpointContext);
473 VerifyImportedWsdlPort(wsdlPort);
474 importedPorts.Add(wsdlPort, endpoint);
477 #pragma warning suppress 56500 // covered by FxCOP
482 WsdlImportException wie = WsdlImportException.Create(wsdlPort, e);
483 LogImportError(wsdlPort, wie);
484 if (errorBehavior == ErrorBehavior.RethrowExceptions)
485 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(wie);
494 static bool TryCreateMessageDescription(WsdlNS.OperationMessage wsdlOperationMessage, OperationDescription operationDescription, out MessageDescription messageDescription)
496 string actionUri = WSAddressingHelper.GetWsaActionUri(wsdlOperationMessage);
497 MessageDirection direction;
499 if (wsdlOperationMessage is WsdlNS.OperationInput)
500 direction = MessageDirection.Input;
501 else if (wsdlOperationMessage is WsdlNS.OperationOutput)
502 direction = MessageDirection.Output;
505 messageDescription = null;
509 messageDescription = new MessageDescription(actionUri, direction);
510 messageDescription.MessageName = WsdlNamingHelper.GetOperationMessageName(wsdlOperationMessage);
511 messageDescription.XsdTypeName = wsdlOperationMessage.Message;
512 operationDescription.Messages.Add(messageDescription);
516 static bool TryCreateFaultDescription(WsdlNS.OperationFault wsdlOperationFault, OperationDescription operationDescription, out FaultDescription faultDescription)
519 if (string.IsNullOrEmpty(wsdlOperationFault.Name))
521 faultDescription = null;
525 string actionUri = WSAddressingHelper.GetWsaActionUri(wsdlOperationFault);
526 faultDescription = new FaultDescription(actionUri);
527 faultDescription.SetNameOnly(new XmlName(wsdlOperationFault.Name, true /*isEncoded*/));
528 operationDescription.Faults.Add(faultDescription);
532 ContractDescription CreateContractDescription(WsdlNS.PortType wsdlPortType, XmlQualifiedName wsdlPortTypeQName)
534 ContractDescription contractDescription;
535 XmlQualifiedName contractQName = WsdlNamingHelper.GetContractName(wsdlPortTypeQName);
536 contractDescription = new ContractDescription(contractQName.Name, contractQName.Namespace);
537 NetSessionHelper.SetSession(contractDescription, wsdlPortType);
538 return contractDescription;
541 OperationDescription CreateOperationDescription(WsdlNS.PortType wsdlPortType, WsdlNS.Operation wsdlOperation, ContractDescription contract)
543 string operationName = WsdlNamingHelper.GetOperationName(wsdlOperation);
544 OperationDescription operationDescription = new OperationDescription(operationName, contract);
545 NetSessionHelper.SetInitiatingTerminating(operationDescription, wsdlOperation);
546 contract.Operations.Add(operationDescription);
547 return operationDescription;
550 Binding CreateBinding(WsdlEndpointConversionContext endpointContext, XmlQualifiedName bindingQName)
554 // either the wsdl:binding has already been imported or the wsdl:port has policy
555 BindingElementCollection bindingElements = ImportPolicyFromWsdl(endpointContext);
556 CustomBinding binding = new CustomBinding(bindingElements);
557 // use decoded form to preserve the user-given friendly name
558 binding.Name = NamingHelper.CodeName(bindingQName.Name);
559 binding.Namespace = bindingQName.Namespace;
564 #pragma warning suppress 56500 // covered by FxCOP
569 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(endpointContext.WsdlBinding, e));
573 ContractDescription GetOrImportContractDescription(XmlQualifiedName wsdlPortTypeQName, out bool wasExistingContractDescription)
575 ContractDescription contractDescription;
577 if (!TryFindExistingContract(wsdlPortTypeQName, out contractDescription))
579 WsdlNS.PortType wsdlPortType = wsdlDocuments.GetPortType(wsdlPortTypeQName);
581 contractDescription = ImportWsdlPortType(wsdlPortType, WsdlPortTypeImportOptions.IgnoreExistingContracts, ErrorBehavior.RethrowExceptions);
583 wasExistingContractDescription = false;
586 wasExistingContractDescription = true;
587 return contractDescription;
590 void ProcessMetadataDocuments(IEnumerable<MetadataSection> metadataSections)
593 foreach (MetadataSection doc in metadataSections)
597 if (doc.Metadata is MetadataReference || doc.Metadata is MetadataLocation)
600 if (doc.Dialect == MetadataSection.ServiceDescriptionDialect)
602 wsdlDocuments.Add(TryConvert<WsdlNS.ServiceDescription>(doc));
604 if (doc.Dialect == MetadataSection.XmlSchemaDialect)
606 xmlSchemas.Add(TryConvert<XmlSchema>(doc));
608 if (doc.Dialect == MetadataSection.PolicyDialect)
610 if (string.IsNullOrEmpty(doc.Identifier))
612 LogImportWarning(SR.GetString(SR.PolicyDocumentMustHaveIdentifier));
616 policyDocuments.Add(doc.Identifier, TryConvert<XmlElement>(doc));
620 #pragma warning suppress 56500 // covered by FxCOP
625 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(doc.Identifier, e));
630 T TryConvert<T>(MetadataSection doc)
634 return ((T)doc.Metadata);
636 catch (InvalidCastException)
638 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(
639 SR.GetString(SR.SFxBadMetadataDialect, doc.Identifier, doc.Dialect, typeof(T).FullName, doc.GetType().FullName)));
643 bool TryFindExistingContract(XmlQualifiedName wsdlPortTypeQName, out ContractDescription existingContract)
645 XmlQualifiedName contractQName = WsdlNamingHelper.GetContractName(wsdlPortTypeQName);
647 // Scan Known Contracts first because wsdl:portType may not be available
648 if (this.KnownContracts.TryGetValue(contractQName, out existingContract))
651 WsdlContractConversionContext contractContext;
652 if (importedPortTypes.TryGetValue(wsdlPortTypeQName, out contractContext))
654 existingContract = contractContext.Contract;
661 void EnsureBeforeImportCalled()
663 if (!beforeImportCalled)
665 foreach (IWsdlImportExtension extension in this.wsdlExtensions)
669 extension.BeforeImport(this.wsdlDocuments, this.xmlSchemas, this.policyDocuments.Values);
671 #pragma warning suppress 56500 // covered by FxCOP
674 this.isFaulted = true;
677 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBeforeImportExtensionException(extension, e));
680 beforeImportCalled = true;
684 void CallImportContract(WsdlContractConversionContext contractConversionContext)
686 foreach (IWsdlImportExtension extension in this.wsdlExtensions)
689 extension.ImportContract(this, contractConversionContext);
691 #pragma warning suppress 56500 // covered by FxCOP
696 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateExtensionException(extension, e));
700 void CallImportEndpoint(WsdlEndpointConversionContext endpointConversionContext)
702 foreach (IWsdlImportExtension extension in this.wsdlExtensions)
705 extension.ImportEndpoint(this, endpointConversionContext);
708 #pragma warning suppress 56500 // covered by FxCOP
713 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateExtensionException(extension, e));
717 void VerifyImportedWsdlPortType(WsdlNS.PortType wsdlPortType)
719 VerifyImportedExtensions(wsdlPortType);
720 foreach (WsdlNS.Operation wsdlOperation in wsdlPortType.Operations)
722 VerifyImportedExtensions(wsdlOperation);
724 foreach (WsdlNS.OperationMessage wsdlOperationMessage in wsdlOperation.Messages)
726 VerifyImportedExtensions(wsdlOperationMessage);
729 foreach (WsdlNS.OperationMessage wsdlOperationMessage in wsdlOperation.Faults)
731 VerifyImportedExtensions(wsdlOperationMessage);
736 void VerifyImportedWsdlBinding(WsdlNS.Binding wsdlBinding)
738 VerifyImportedExtensions(wsdlBinding);
739 foreach (WsdlNS.OperationBinding wsdlOperationBinding in wsdlBinding.Operations)
741 VerifyImportedExtensions(wsdlOperationBinding);
743 if (wsdlOperationBinding.Input != null)
745 VerifyImportedExtensions(wsdlOperationBinding.Input);
748 if (wsdlOperationBinding.Output != null)
750 VerifyImportedExtensions(wsdlOperationBinding.Output);
753 foreach (WsdlNS.MessageBinding wsdlMessageBinding in wsdlOperationBinding.Faults)
755 VerifyImportedExtensions(wsdlMessageBinding);
760 void VerifyImportedWsdlPort(WsdlNS.Port wsdlPort)
762 VerifyImportedExtensions(wsdlPort);
765 void VerifyImportedExtensions(WsdlNS.NamedItem item)
767 foreach (object ext in item.Extensions)
769 if (item.Extensions.IsHandled(ext))
772 XmlQualifiedName qName = GetUnhandledExtensionQName(ext, item);
774 if (item.Extensions.IsRequired(ext) || IsNonSoapWsdl11BindingExtension(ext))
776 string errorMsg = SR.GetString(SR.RequiredWSDLExtensionIgnored, qName.Name, qName.Namespace);
777 WsdlImportException wie = WsdlImportException.Create(item, new InvalidOperationException(errorMsg));
778 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(wie);
782 string xPath = CreateXPathString(item);
783 string errorMsg = SR.GetString(SR.OptionalWSDLExtensionIgnored, qName.Name, qName.Namespace, xPath);
784 this.Errors.Add(new MetadataConversionError(errorMsg, true));
789 static bool IsNonSoapWsdl11BindingExtension(object ext)
791 if (ext is WsdlNS.HttpAddressBinding
792 || ext is WsdlNS.HttpBinding
793 || ext is WsdlNS.HttpOperationBinding
794 || ext is WsdlNS.HttpUrlEncodedBinding
795 || ext is WsdlNS.HttpUrlReplacementBinding
796 || ext is WsdlNS.MimeContentBinding
797 || ext is WsdlNS.MimeMultipartRelatedBinding
798 || ext is WsdlNS.MimePart
799 || ext is WsdlNS.MimeTextBinding
800 || ext is WsdlNS.MimeXmlBinding
810 XmlQualifiedName GetUnhandledExtensionQName(object extension, WsdlNS.NamedItem item)
812 XmlElement element = extension as XmlElement;
815 return new XmlQualifiedName(element.LocalName, element.NamespaceURI);
817 else if (extension is WsdlNS.ServiceDescriptionFormatExtension)
819 WsdlConfigNS.XmlFormatExtensionAttribute[] xfeAttributes
820 = (WsdlConfigNS.XmlFormatExtensionAttribute[])ServiceReflector.GetCustomAttributes(extension.GetType(),
821 typeof(WsdlConfigNS.XmlFormatExtensionAttribute), false);
823 if (xfeAttributes.Length > 0)
825 return new XmlQualifiedName(xfeAttributes[0].ElementName, xfeAttributes[0].Namespace);
828 WsdlImportException wie = WsdlImportException.Create(item, new InvalidOperationException(SR.GetString(SR.UnknownWSDLExtensionIgnored, extension.GetType().AssemblyQualifiedName)));
829 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(wie);
832 internal static class Binding2DescriptionHelper
834 internal static OperationDescription FindOperationDescription(WsdlNS.OperationBinding wsdlOperationBinding, WsdlNS.ServiceDescriptionCollection wsdlDocuments, WsdlEndpointConversionContext endpointContext)
837 OperationDescription operation;
838 if (endpointContext.ContractConversionContext != null)
840 WsdlNS.Operation wsdlOperation = FindWsdlOperation(wsdlOperationBinding, wsdlDocuments);
841 operation = endpointContext.ContractConversionContext.GetOperationDescription(wsdlOperation);
845 operation = FindOperationDescription(endpointContext.Endpoint.Contract, wsdlOperationBinding);
850 internal static WsdlNS.MessageBinding FindMessageBinding(WsdlNS.OperationBinding wsdlOperationBinding, MessageDescription message)
852 WsdlNS.MessageBinding wsdlMessageBinding;
853 if (message.Direction == MessageDirection.Input)
855 wsdlMessageBinding = wsdlOperationBinding.Input;
859 wsdlMessageBinding = wsdlOperationBinding.Output;
861 return wsdlMessageBinding;
864 internal static WsdlNS.FaultBinding FindFaultBinding(WsdlNS.OperationBinding wsdlOperationBinding, FaultDescription fault)
866 foreach (WsdlNS.FaultBinding faultBinding in wsdlOperationBinding.Faults)
867 if (faultBinding.Name == fault.Name)
872 static WsdlNS.Operation FindWsdlOperation(WsdlNS.OperationBinding wsdlOperationBinding, WsdlNS.ServiceDescriptionCollection wsdlDocuments)
874 WsdlNS.PortType wsdlPortType = wsdlDocuments.GetPortType(wsdlOperationBinding.Binding.Type);
876 string wsdlOperationBindingName = wsdlOperationBinding.Name;
878 if (wsdlOperationBindingName == null)
880 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidWsdlBindingOpNoName, wsdlOperationBinding.Binding.Name)));
883 WsdlNS.Operation partialMatchResult = null;
885 foreach (WsdlNS.Operation wsdlOperation in wsdlPortType.Operations)
887 switch (Match(wsdlOperationBinding, wsdlOperation))
889 case MatchResult.None:
891 case MatchResult.Partial:
892 partialMatchResult = wsdlOperation;
894 case MatchResult.Exact:
895 return wsdlOperation;
897 Fx.AssertAndFailFast("Unexpected MatchResult value.");
902 if (partialMatchResult != null)
904 return partialMatchResult;
908 //unable to find wsdloperation for wsdlOperationBinding, invalid wsdl binding
909 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidWsdlBindingOpMismatch2, wsdlOperationBinding.Binding.Name, wsdlOperationBinding.Name)));
913 internal enum MatchResult
920 internal static MatchResult Match(WsdlNS.OperationBinding wsdlOperationBinding, WsdlNS.Operation wsdlOperation)
922 // This method checks if there is a match based on Names, between the specified OperationBinding and Operation.
923 // When searching for the Operation associated with an OperationBinding, we need to return an exact match if possible,
924 // or a partial match otherwise (when some of the Names are null).
925 // Bug 16833 @ CSDMain requires that partial matches are allowed, while the TFS bug 477838 requires that exact matches are done (when possible).
926 if (wsdlOperationBinding.Name != wsdlOperation.Name)
928 return MatchResult.None;
931 MatchResult result = MatchResult.Exact;
933 foreach (WsdlNS.OperationMessage wsdlOperationMessage in wsdlOperation.Messages)
935 WsdlNS.MessageBinding wsdlMessageBinding;
936 if (wsdlOperationMessage is WsdlNS.OperationInput)
937 wsdlMessageBinding = wsdlOperationBinding.Input;
939 wsdlMessageBinding = wsdlOperationBinding.Output;
941 if (wsdlMessageBinding == null)
943 return MatchResult.None;
946 switch (MatchOperationParameterName(wsdlMessageBinding, wsdlOperationMessage))
948 case MatchResult.None:
949 return MatchResult.None;
950 case MatchResult.Partial:
951 result = MatchResult.Partial;
959 static MatchResult MatchOperationParameterName(WsdlNS.MessageBinding wsdlMessageBinding, WsdlNS.OperationMessage wsdlOperationMessage)
961 string wsdlOperationMessageName = wsdlOperationMessage.Name;
962 string wsdlMessageBindingName = wsdlMessageBinding.Name;
964 if (wsdlOperationMessageName == wsdlMessageBindingName)
966 return MatchResult.Exact;
969 string wsdlOperationMessageDecodedName = WsdlNamingHelper.GetOperationMessageName(wsdlOperationMessage).DecodedName;
970 if ((wsdlOperationMessageName == null) && (wsdlMessageBindingName == wsdlOperationMessageDecodedName))
972 return MatchResult.Partial;
974 else if ((wsdlMessageBindingName == null) && (wsdlOperationMessageName == wsdlOperationMessageDecodedName))
976 return MatchResult.Partial;
980 return MatchResult.None;
984 static OperationDescription FindOperationDescription(ContractDescription contract, WsdlNS.OperationBinding wsdlOperationBinding)
986 foreach (OperationDescription operationDescription in contract.Operations)
988 if (CompareOperations(operationDescription, contract, wsdlOperationBinding))
989 return operationDescription;
992 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToLocateOperation2, wsdlOperationBinding.Name, contract.Name)));
995 static bool CompareOperations(OperationDescription operationDescription, ContractDescription parentContractDescription, WsdlNS.OperationBinding wsdlOperationBinding)
997 string wsdlOperationName = WsdlExporter.WsdlNamingHelper.GetWsdlOperationName(operationDescription, parentContractDescription);
999 if (wsdlOperationName != wsdlOperationBinding.Name)
1002 if (operationDescription.Messages.Count > 2)
1005 // Either both have output message or neither have an output message;
1006 if (FindMessage(operationDescription.Messages, MessageDirection.Output) != (wsdlOperationBinding.Output != null))
1009 // Either both have output message or neither have an output message;
1010 if (FindMessage(operationDescription.Messages, MessageDirection.Input) != (wsdlOperationBinding.Input != null))
1017 private static bool FindMessage(MessageDescriptionCollection messageDescriptionCollection, MessageDirection transferDirection)
1019 foreach (MessageDescription message in messageDescriptionCollection)
1020 if (message.Direction == transferDirection)
1027 internal static class WSAddressingHelper
1029 internal static string GetWsaActionUri(WsdlNS.OperationMessage wsdlOperationMessage)
1031 string actionUri = FindWsaActionAttribute(wsdlOperationMessage);
1032 return (actionUri == null) ? CreateDefaultWsaActionUri(wsdlOperationMessage) : actionUri;
1035 internal static string FindWsaActionAttribute(WsdlNS.OperationMessage wsdlOperationMessage)
1037 XmlAttribute[] attributes = wsdlOperationMessage.ExtensibleAttributes;
1038 if (attributes != null && attributes.Length > 0)
1040 foreach (XmlAttribute attribute in attributes)
1042 if ((attribute.NamespaceURI == MetadataStrings.AddressingWsdl.NamespaceUri
1043 || attribute.NamespaceURI == MetadataStrings.AddressingMetadata.NamespaceUri)
1044 && attribute.LocalName == MetadataStrings.AddressingMetadata.Action)
1046 return attribute.Value;
1054 static string CreateDefaultWsaActionUri(WsdlNS.OperationMessage wsdlOperationMessage)
1056 if (wsdlOperationMessage is WsdlNS.OperationFault)
1057 return AddressingVersion.WSAddressing10.DefaultFaultAction;
1059 // We figure out default action. All specifications' rules below are the same.
1060 // Using [WSDL Binding W3C Working Draft 13 April 2005] Section 3.3
1061 // Using [WSDL Binding W3C Candidate Recommendation 29 May 2006] Section 4.4.4
1062 // Using [Metadata W3C Working Draft 13 16 May 2007] Section 4.4.4
1064 string ns = wsdlOperationMessage.Operation.PortType.ServiceDescription.TargetNamespace ?? string.Empty;
1065 string portTypeName = wsdlOperationMessage.Operation.PortType.Name;
1066 XmlName operationMessageName = WsdlNamingHelper.GetOperationMessageName(wsdlOperationMessage);
1068 string delimiter = ns.StartsWith("urn:", StringComparison.OrdinalIgnoreCase) ? ":" : "/";
1070 string baseActionUri = ns.EndsWith(delimiter, StringComparison.OrdinalIgnoreCase) ? ns : ns + delimiter;
1072 string actionUri = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3}", baseActionUri, portTypeName, delimiter, operationMessageName.EncodedName);
1077 internal static EndpointAddress ImportAddress(WsdlNS.Port wsdlPort)
1079 //Try to read Endpoint Address from WsdlPort
1080 if (wsdlPort != null)
1082 XmlElement addressing10Element = wsdlPort.Extensions.Find(AddressingStrings.EndpointReference, Addressing10Strings.Namespace);
1083 XmlElement addressing200408Element = wsdlPort.Extensions.Find(AddressingStrings.EndpointReference, Addressing200408Strings.Namespace);
1084 WsdlNS.SoapAddressBinding soapAddressBinding = (WsdlNS.SoapAddressBinding)wsdlPort.Extensions.Find(typeof(WsdlNS.SoapAddressBinding));
1087 if (addressing10Element != null)
1089 return EndpointAddress.ReadFrom(AddressingVersion.WSAddressing10, new XmlNodeReader(addressing10Element));
1091 if (addressing200408Element != null)
1093 return EndpointAddress.ReadFrom(AddressingVersion.WSAddressingAugust2004, new XmlNodeReader(addressing200408Element));
1095 else if (soapAddressBinding != null)
1097 return new EndpointAddress(soapAddressBinding.Location);
1104 internal static AddressingVersion FindAddressingVersion(PolicyConversionContext policyContext)
1106 if (PolicyConversionContext.FindAssertion(policyContext.GetBindingAssertions(),
1107 MetadataStrings.Addressing10.WsdlBindingPolicy.UsingAddressing,
1108 MetadataStrings.Addressing10.WsdlBindingPolicy.NamespaceUri, true /*remove*/) != null)
1110 return AddressingVersion.WSAddressing10;
1112 else if (PolicyConversionContext.FindAssertion(policyContext.GetBindingAssertions(),
1113 MetadataStrings.Addressing10.MetadataPolicy.Addressing,
1114 MetadataStrings.Addressing10.MetadataPolicy.NamespaceUri, true /*remove*/) != null)
1116 return AddressingVersion.WSAddressing10;
1118 else if (PolicyConversionContext.FindAssertion(policyContext.GetBindingAssertions(),
1119 MetadataStrings.Addressing200408.Policy.UsingAddressing,
1120 MetadataStrings.Addressing200408.Policy.NamespaceUri, true /*remove*/) != null)
1122 return AddressingVersion.WSAddressingAugust2004;
1126 return AddressingVersion.None;
1130 internal static SupportedAddressingMode DetermineSupportedAddressingMode(MetadataImporter importer, PolicyConversionContext context)
1132 // Do not remove this assertion - the message encoding binding element importer owns it.
1133 XmlElement addressingAssertion = PolicyConversionContext.FindAssertion(context.GetBindingAssertions(),
1134 MetadataStrings.Addressing10.MetadataPolicy.Addressing, MetadataStrings.Addressing10.MetadataPolicy.NamespaceUri, false);
1136 if (addressingAssertion != null)
1138 XmlElement policyElement = null;
1139 foreach (XmlNode node in addressingAssertion.ChildNodes)
1141 if (node is XmlElement && MetadataSection.IsPolicyElement((XmlElement)node))
1143 policyElement = (XmlElement)node;
1148 if (policyElement == null)
1150 string message = SR.GetString(SR.ElementRequired, MetadataStrings.Addressing10.MetadataPolicy.Prefix,
1151 MetadataStrings.Addressing10.MetadataPolicy.Addressing, MetadataStrings.WSPolicy.Prefix,
1152 MetadataStrings.WSPolicy.Elements.Policy);
1154 importer.Errors.Add(new MetadataConversionError(message, false));
1155 return SupportedAddressingMode.Anonymous;
1158 IEnumerable<IEnumerable<XmlElement>> alternatives = importer.NormalizePolicy(new XmlElement[] { policyElement });
1159 foreach (IEnumerable<XmlElement> alternative in alternatives)
1161 foreach (XmlElement element in alternative)
1163 if (element.NamespaceURI == MetadataStrings.Addressing10.MetadataPolicy.NamespaceUri)
1165 if (element.LocalName == MetadataStrings.Addressing10.MetadataPolicy.NonAnonymousResponses)
1167 return SupportedAddressingMode.NonAnonymous;
1169 else if (element.LocalName == MetadataStrings.Addressing10.MetadataPolicy.AnonymousResponses)
1171 return SupportedAddressingMode.Anonymous;
1178 return SupportedAddressingMode.Anonymous;
1182 static class WsdlNamingHelper
1184 internal static XmlQualifiedName GetBindingName(WsdlNS.Binding wsdlBinding)
1186 XmlName xmlName = new XmlName(wsdlBinding.Name, true /*isEncoded*/);
1187 return new XmlQualifiedName(xmlName.EncodedName, wsdlBinding.ServiceDescription.TargetNamespace);
1190 internal static XmlQualifiedName GetBindingName(WsdlNS.Port wsdlPort)
1192 // Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_'
1193 XmlName xmlName = new XmlName(string.Format(CultureInfo.InvariantCulture, "{0}_{1}", wsdlPort.Service.Name, wsdlPort.Name), true /*isEncoded*/);
1194 return new XmlQualifiedName(xmlName.EncodedName, wsdlPort.Service.ServiceDescription.TargetNamespace);
1197 internal static XmlName GetEndpointName(WsdlNS.Port wsdlPort)
1199 return new XmlName(wsdlPort.Name, true /*isEncoded*/);
1202 internal static XmlQualifiedName GetContractName(XmlQualifiedName wsdlPortTypeQName)
1204 return wsdlPortTypeQName;
1207 internal static string GetOperationName(WsdlNS.Operation wsdlOperation)
1209 return wsdlOperation.Name;
1212 internal static XmlName GetOperationMessageName(WsdlNS.OperationMessage wsdlOperationMessage)
1214 string messageName = null;
1215 if (!string.IsNullOrEmpty(wsdlOperationMessage.Name))
1217 messageName = wsdlOperationMessage.Name;
1219 else if (wsdlOperationMessage.Operation.Messages.Count == 1)
1221 messageName = wsdlOperationMessage.Operation.Name;
1223 else if (wsdlOperationMessage.Operation.Messages.IndexOf(wsdlOperationMessage) == 0)
1225 if (wsdlOperationMessage is WsdlNS.OperationInput)
1226 messageName = wsdlOperationMessage.Operation.Name + "Request";
1227 else if (wsdlOperationMessage is WsdlNS.OperationOutput)
1228 messageName = wsdlOperationMessage.Operation.Name + "Solicit";
1230 else if (wsdlOperationMessage.Operation.Messages.IndexOf(wsdlOperationMessage) == 1)
1232 messageName = wsdlOperationMessage.Operation.Name + "Response";
1236 // Microsoft: why this is an Assert, and not an exception?
1237 Fx.Assert("Unsupported WSDL OM (More than 2 OperationMessages encountered in an Operation or WsdlOM is invalid)");
1239 // names the come from service description documents have to be valid NCNames; XmlName.ctor will validate.
1240 return new XmlName(messageName, true /*isEncoded*/);
1244 internal static class NetSessionHelper
1246 internal static void SetInitiatingTerminating(OperationDescription operationDescription, WsdlNS.Operation wsdlOperation)
1248 XmlAttribute isInitiating = FindAttribute(wsdlOperation.ExtensibleAttributes, WsdlExporter.NetSessionHelper.IsInitiating,
1249 WsdlExporter.NetSessionHelper.NamespaceUri);
1251 if (isInitiating != null)
1253 if (isInitiating.Value == WsdlExporter.NetSessionHelper.True)
1255 operationDescription.IsInitiating = true;
1257 if (isInitiating.Value == WsdlExporter.NetSessionHelper.False)
1259 operationDescription.IsInitiating = false;
1263 XmlAttribute isTerminating = FindAttribute(wsdlOperation.ExtensibleAttributes, WsdlExporter.NetSessionHelper.IsTerminating,
1264 WsdlExporter.NetSessionHelper.NamespaceUri);
1266 if (isTerminating != null)
1268 if (isTerminating.Value == WsdlExporter.NetSessionHelper.True)
1270 operationDescription.IsTerminating = true;
1272 if (isTerminating.Value == WsdlExporter.NetSessionHelper.False)
1274 operationDescription.IsTerminating = false;
1279 internal static void SetSession(ContractDescription contractDescription, WsdlNS.PortType wsdlPortType)
1281 XmlAttribute usingSession = FindAttribute(wsdlPortType.ExtensibleAttributes, WsdlExporter.NetSessionHelper.UsingSession,
1282 WsdlExporter.NetSessionHelper.NamespaceUri);
1284 if (usingSession != null)
1286 if (usingSession.Value == WsdlExporter.NetSessionHelper.True)
1288 contractDescription.SessionMode = SessionMode.Required;
1290 if (usingSession.Value == WsdlExporter.NetSessionHelper.False)
1292 contractDescription.SessionMode = SessionMode.NotAllowed;
1297 static XmlAttribute FindAttribute(XmlAttribute[] attributes, string localName, string ns)
1299 if (attributes != null)
1301 foreach (XmlAttribute attribute in attributes)
1303 if (attribute.LocalName == localName && attribute.NamespaceURI == ns)
1313 internal static class SoapInPolicyWorkaroundHelper
1315 public const string soapTransportUriKey = "TransportBindingElementImporter.TransportUri";
1316 const string workaroundNS = NamingHelper.DefaultNamespace + "temporaryworkaround";
1317 const string bindingAttrName = "bindingName";
1318 const string bindingAttrNamespace = "bindingNamespace";
1319 static XmlDocument xmlDocument;
1321 static public void InsertAdHocPolicy(WsdlNS.Binding wsdlBinding, string value, string key)
1323 XmlQualifiedName wsdlBindingQName = new XmlQualifiedName(wsdlBinding.Name, wsdlBinding.ServiceDescription.TargetNamespace);
1324 string id = AddPolicyUri(wsdlBinding, key);
1325 InsertPolicy(key, id, wsdlBinding.ServiceDescription, value, wsdlBindingQName);
1328 static public string FindAdHocTransportPolicy(PolicyConversionContext policyContext, out XmlQualifiedName wsdlBindingQName)
1330 return FindAdHocPolicy(policyContext, soapTransportUriKey, out wsdlBindingQName);
1333 static public string FindAdHocPolicy(PolicyConversionContext policyContext, string key, out XmlQualifiedName wsdlBindingQName)
1335 if (policyContext == null)
1336 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("policyContext");
1338 XmlElement policy = PolicyConversionContext.FindAssertion(policyContext.GetBindingAssertions(), key, workaroundNS, true);
1341 wsdlBindingQName = new XmlQualifiedName(policy.Attributes[bindingAttrName].Value, policy.Attributes[bindingAttrNamespace].Value);
1342 return policy.InnerText;
1346 wsdlBindingQName = null;
1351 static string AddPolicyUri(WsdlNS.Binding wsdlBinding, string name)
1353 string policyUris = ReadPolicyUris(wsdlBinding);
1354 string id = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}_BindingAdHocPolicy", wsdlBinding.Name, name);
1355 string newPolicyUris = string.Format(System.Globalization.CultureInfo.InvariantCulture, "#{0} {1}", id, policyUris).Trim();
1356 WritePolicyUris(wsdlBinding, newPolicyUris);
1360 static XmlDocument XmlDoc
1364 if (xmlDocument == null)
1366 NameTable nameTable = new NameTable();
1367 nameTable.Add(MetadataStrings.WSPolicy.Elements.Policy);
1368 nameTable.Add(MetadataStrings.WSPolicy.Elements.All);
1369 nameTable.Add(MetadataStrings.WSPolicy.Elements.ExactlyOne);
1370 nameTable.Add(MetadataStrings.WSPolicy.Attributes.PolicyURIs);
1371 nameTable.Add(MetadataStrings.Wsu.Attributes.Id);
1372 xmlDocument = new XmlDocument(nameTable);
1378 static void WritePolicyUris(WsdlNS.DocumentableItem item, string newValue)
1382 XmlAttribute[] attributes = item.ExtensibleAttributes;
1383 if (attributes != null && attributes.Length > 0)
1385 foreach (XmlAttribute attribute in attributes)
1386 if (MetadataImporter.PolicyHelper.IsPolicyURIs(attribute))
1388 attribute.Value = newValue;
1392 i = attributes.Length;
1393 Array.Resize<XmlAttribute>(ref attributes, i + 1);
1400 attributes = new XmlAttribute[1];
1403 attributes[i] = CreatePolicyURIsAttribute(newValue);
1404 item.ExtensibleAttributes = attributes;
1407 static XmlAttribute CreatePolicyURIsAttribute(string value)
1409 XmlAttribute attribute = XmlDoc.CreateAttribute(MetadataStrings.WSPolicy.Prefix,
1410 MetadataStrings.WSPolicy.Attributes.PolicyURIs,
1411 MetadataStrings.WSPolicy.NamespaceUri);
1413 attribute.Value = value;
1417 static string ReadPolicyUris(WsdlNS.DocumentableItem item)
1420 XmlAttribute[] attributes = item.ExtensibleAttributes;
1421 if (attributes != null && attributes.Length > 0)
1423 foreach (XmlAttribute attribute in attributes)
1425 if (MetadataImporter.PolicyHelper.IsPolicyURIs(attribute))
1427 return attribute.Value;
1432 return string.Empty;
1435 static void InsertPolicy(string key, string id, WsdlNS.ServiceDescription policyWsdl, string value, XmlQualifiedName wsdlBindingQName)
1438 // Create [wsp:Policy]
1439 XmlElement policyElement = CreatePolicyElement(key, value, wsdlBindingQName);
1441 //Create [wsp:Policy/@wsu:Id]
1442 XmlAttribute idAttribute = XmlDoc.CreateAttribute(MetadataStrings.Wsu.Prefix,
1443 MetadataStrings.Wsu.Attributes.Id,
1444 MetadataStrings.Wsu.NamespaceUri);
1445 idAttribute.Value = id;
1446 policyElement.SetAttributeNode(idAttribute);
1448 // Add wsp:Policy To WSDL
1449 policyWsdl.Extensions.Add(policyElement);
1453 static XmlElement CreatePolicyElement(string elementName, string value, XmlQualifiedName wsdlBindingQName)
1456 // Create [wsp:Policy]
1457 XmlElement policyElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix,
1458 MetadataStrings.WSPolicy.Elements.Policy,
1459 MetadataStrings.WSPolicy.NamespaceUri);
1461 // Create [wsp:Policy/wsp:ExactlyOne]
1462 XmlElement exactlyOneElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix,
1463 MetadataStrings.WSPolicy.Elements.ExactlyOne,
1464 MetadataStrings.WSPolicy.NamespaceUri);
1465 policyElement.AppendChild(exactlyOneElement);
1467 // Create [wsp:Policy/wsp:ExactlyOne/wsp:All]
1468 XmlElement allElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix,
1469 MetadataStrings.WSPolicy.Elements.All,
1470 MetadataStrings.WSPolicy.NamespaceUri);
1471 exactlyOneElement.AppendChild(allElement);
1473 // Add [wsp:Policy/wsp:ExactlyOne/wsp:All/*]
1474 XmlElement workaroundElement = xmlDocument.CreateElement(elementName, workaroundNS);
1475 workaroundElement.InnerText = value;
1477 XmlAttribute bindingName = xmlDocument.CreateAttribute(bindingAttrName);
1478 bindingName.Value = wsdlBindingQName.Name;
1479 workaroundElement.Attributes.Append(bindingName);
1481 XmlAttribute bindingNamespace = xmlDocument.CreateAttribute(bindingAttrNamespace);
1482 bindingNamespace.Value = wsdlBindingQName.Namespace;
1483 workaroundElement.Attributes.Append(bindingNamespace);
1485 workaroundElement.Attributes.Append(bindingNamespace);
1488 allElement.AppendChild(workaroundElement);
1490 return policyElement;
1493 internal static void InsertAdHocTransportPolicy(WsdlNS.ServiceDescriptionCollection wsdlDocuments)
1495 foreach (WsdlNS.ServiceDescription wsdl in wsdlDocuments)
1498 foreach (WsdlNS.Binding wsdlBinding in wsdl.Bindings)
1500 if (WsdlImporter.WsdlPolicyReader.ContainsPolicy(wsdlBinding))
1502 WsdlNS.SoapBinding soapBinding = (WsdlNS.SoapBinding)wsdlBinding.Extensions.Find(typeof(WsdlNS.SoapBinding));
1503 if (soapBinding != null)
1505 .SoapInPolicyWorkaroundHelper
1506 .InsertAdHocPolicy(wsdlBinding, soapBinding.Transport, soapTransportUriKey);
1513 IEnumerable<WsdlNS.Binding> FindBindingsForPortType(WsdlNS.PortType wsdlPortType)
1515 foreach (WsdlNS.Binding wsdlBinding in GetAllBindings())
1517 if (wsdlBinding.Type.Name == wsdlPortType.Name
1518 && wsdlBinding.Type.Namespace == wsdlPortType.ServiceDescription.TargetNamespace)
1519 yield return wsdlBinding;
1523 IEnumerable<WsdlNS.Binding> FindBindingsForContract(ContractDescription contract)
1525 XmlQualifiedName qName = WsdlExporter.WsdlNamingHelper.GetPortTypeQName(contract);
1526 foreach (WsdlNS.Binding wsdlBinding in GetAllBindings())
1528 if (wsdlBinding.Type.Name == qName.Name
1529 && wsdlBinding.Type.Namespace == qName.Namespace)
1530 yield return wsdlBinding;
1534 IEnumerable<WsdlNS.Port> FindPortsForBinding(WsdlNS.Binding binding)
1536 foreach (WsdlNS.Port wsdlPort in GetAllPorts())
1538 if (wsdlPort.Binding.Name == binding.Name && wsdlPort.Binding.Namespace == binding.ServiceDescription.TargetNamespace)
1539 yield return wsdlPort;
1543 IEnumerable<WsdlNS.Binding> GetAllBindings()
1545 foreach (WsdlNS.ServiceDescription wsdl in this.WsdlDocuments)
1547 foreach (WsdlNS.Binding wsdlBinding in wsdl.Bindings)
1549 yield return wsdlBinding;
1554 IEnumerable<WsdlNS.Port> GetAllPorts()
1556 foreach (WsdlNS.ServiceDescription wsdl in this.WsdlDocuments)
1558 foreach (WsdlNS.Service wsdlService in wsdl.Services)
1560 foreach (WsdlNS.Port wsdlPort in wsdlService.Ports)
1562 yield return wsdlPort;
1568 [Fx.Tag.SecurityNote(Critical = "Uses ClientSection.UnsafeGetSection to get config in PT.",
1569 Safe = "Does not leak config object, just picks up extensions.")]
1570 [SecuritySafeCritical]
1571 static Collection<IWsdlImportExtension> LoadWsdlExtensionsFromConfig()
1573 return ConfigNS.ClientSection.UnsafeGetSection().Metadata.LoadWsdlImportExtensions();
1576 internal static IEnumerable<MetadataSection> CreateMetadataDocuments(WsdlNS.ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, IEnumerable<XmlElement> policyDocuments)
1579 if (wsdlDocuments != null)
1580 foreach (WsdlNS.ServiceDescription wsdl in wsdlDocuments)
1581 yield return MetadataSection.CreateFromServiceDescription(wsdl);
1583 if (xmlSchemas != null)
1584 foreach (XmlSchema schema in xmlSchemas.Schemas())
1585 yield return MetadataSection.CreateFromSchema(schema);
1587 if (policyDocuments != null)
1588 foreach (XmlElement policyDocument in policyDocuments)
1589 yield return MetadataSection.CreateFromPolicy(policyDocument, null);
1592 BindingElementCollection ImportPolicyFromWsdl(WsdlEndpointConversionContext endpointContext)
1594 PolicyAlternatives policyAlternatives = this.PolicyReader.GetPolicyAlternatives(endpointContext);
1595 IEnumerable<PolicyConversionContext> policyContexts = GetPolicyConversionContextEnumerator(endpointContext.Endpoint, policyAlternatives, this.Quotas);
1596 PolicyConversionContext firstContext = null;
1598 StringBuilder unImportedPolicyMessage = null;
1599 int policyConversionContextsSeen = 0; //limit on the number of alternatives that we'll evaluate
1600 foreach (PolicyConversionContext policyConversionContext in policyContexts)
1602 if (firstContext == null)
1603 firstContext = policyConversionContext;
1604 if (this.TryImportPolicy(policyConversionContext))
1606 return policyConversionContext.BindingElements;
1610 AppendUnImportedPolicyErrorMessage(ref unImportedPolicyMessage, endpointContext, policyConversionContext);
1613 if (++policyConversionContextsSeen >= this.Quotas.MaxPolicyConversionContexts)
1619 // we failed to import policy for all PolicyConversionContexts, lets pick one context (the first one)
1620 // and wrap all unprocessed assertion in UnrecognizedAssertionsBindingElement
1621 if (firstContext != null)
1623 #pragma warning suppress 56506
1624 firstContext.BindingElements.Insert(0, CollectUnrecognizedAssertions(firstContext, endpointContext));
1625 LogImportWarning(unImportedPolicyMessage.ToString());
1626 return firstContext.BindingElements;
1628 // Consider: a /verbose option for svcutil...
1629 if (endpointContext.WsdlPort != null)
1631 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(endpointContext.WsdlPort, new InvalidOperationException(SR.GetString(SR.NoUsablePolicyAssertions))));
1635 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(endpointContext.WsdlBinding, new InvalidOperationException(SR.GetString(SR.NoUsablePolicyAssertions))));
1639 static UnrecognizedAssertionsBindingElement CollectUnrecognizedAssertions(PolicyConversionContext policyContext, WsdlEndpointConversionContext endpointContext)
1641 XmlQualifiedName bindingQName = new XmlQualifiedName(endpointContext.WsdlBinding.Name, endpointContext.WsdlBinding.ServiceDescription.TargetNamespace);
1642 UnrecognizedAssertionsBindingElement unknownBindingElement = new UnrecognizedAssertionsBindingElement(bindingQName, policyContext.GetBindingAssertions());
1643 foreach (OperationDescription operation in policyContext.Contract.Operations)
1645 if (policyContext.GetOperationBindingAssertions(operation).Count != 0)
1647 unknownBindingElement.Add(operation, policyContext.GetOperationBindingAssertions(operation));
1650 foreach (MessageDescription message in operation.Messages)
1652 if (policyContext.GetMessageBindingAssertions(message).Count != 0)
1654 unknownBindingElement.Add(message, policyContext.GetMessageBindingAssertions(message));
1658 return unknownBindingElement;
1661 static void AppendUnImportedPolicyErrorMessage(ref StringBuilder unImportedPolicyMessage, WsdlEndpointConversionContext endpointContext, PolicyConversionContext policyContext)
1663 if (unImportedPolicyMessage == null)
1665 unImportedPolicyMessage = new StringBuilder(SR.GetString(SR.UnabletoImportPolicy));
1669 unImportedPolicyMessage.AppendLine();
1672 if (policyContext.GetBindingAssertions().Count != 0)
1673 AddUnImportedPolicyString(unImportedPolicyMessage, endpointContext.WsdlBinding, policyContext.GetBindingAssertions());
1675 foreach (OperationDescription operation in policyContext.Contract.Operations)
1677 if (policyContext.GetOperationBindingAssertions(operation).Count != 0)
1679 AddUnImportedPolicyString(unImportedPolicyMessage,
1680 endpointContext.GetOperationBinding(operation),
1681 policyContext.GetOperationBindingAssertions(operation));
1684 foreach (MessageDescription message in operation.Messages)
1686 if (policyContext.GetMessageBindingAssertions(message).Count != 0)
1688 AddUnImportedPolicyString(unImportedPolicyMessage,
1689 endpointContext.GetMessageBinding(message),
1690 policyContext.GetMessageBindingAssertions(message));
1697 static void AddUnImportedPolicyString(StringBuilder stringBuilder, WsdlNS.NamedItem item, IEnumerable<XmlElement> unimportdPolicy)
1699 stringBuilder.AppendLine(SR.GetString(SR.UnImportedAssertionList, CreateXPathString(item)));
1700 // do not putput duplicated assetions
1701 Dictionary<XmlElement, XmlElement> unique = new Dictionary<XmlElement, XmlElement>();
1702 int uniqueAsserions = 0;
1703 foreach (XmlElement element in unimportdPolicy)
1705 if (unique.ContainsKey(element))
1707 unique.Add(element, element);
1709 if (uniqueAsserions > 128)
1711 stringBuilder.Append("..");
1712 stringBuilder.AppendLine();
1715 WriteElement(element, stringBuilder);
1719 static void WriteElement(XmlElement element, StringBuilder stringBuilder)
1721 stringBuilder.Append(" <");
1722 stringBuilder.Append(element.Name);
1723 if (!string.IsNullOrEmpty(element.NamespaceURI))
1725 stringBuilder.Append(' ');
1726 stringBuilder.Append("xmlns");
1727 if (!string.IsNullOrEmpty(element.Prefix))
1729 stringBuilder.Append(':');
1730 stringBuilder.Append(element.Prefix);
1732 stringBuilder.Append('=');
1733 stringBuilder.Append('\'');
1734 stringBuilder.Append(element.NamespaceURI);
1735 stringBuilder.Append('\'');
1737 stringBuilder.Append(">..</");
1738 stringBuilder.Append(element.Name);
1739 stringBuilder.Append('>');
1740 stringBuilder.AppendLine();
1743 const string xPathDocumentFormatString = "//wsdl:definitions[@targetNamespace='{0}']";
1744 const string xPathItemSubFormatString = "/wsdl:{0}";
1745 const string xPathNamedItemSubFormatString = xPathItemSubFormatString + "[@name='{1}']";
1747 static string GetElementName(WsdlNS.NamedItem item)
1749 if (item is WsdlNS.PortType)
1750 return "wsdl:portType";
1751 else if (item is WsdlNS.Binding)
1752 return "wsdl:binding";
1753 else if (item is WsdlNS.ServiceDescription)
1754 return "wsdl:definitions";
1755 else if (item is WsdlNS.Service)
1756 return "wsdl:service";
1757 else if (item is WsdlNS.Message)
1758 return "wsdl:message";
1759 else if (item is WsdlNS.Operation)
1760 return "wsdl:operation";
1761 else if (item is WsdlNS.Port)
1765 Fx.Assert("GetElementName Method should be updated to support " + item.GetType());
1770 static string CreateXPathString(WsdlNS.NamedItem item)
1773 return SR.GetString(SR.XPathUnavailable);
1774 string nameValue = item.Name;
1777 string rest = string.Empty;
1778 string itemPath = string.Empty;
1780 GetXPathParameters(item, out wsdlNs, out localName, ref nameValue, ref rest);
1781 string documentPath = string.Format(CultureInfo.InvariantCulture, xPathDocumentFormatString, wsdlNs);
1783 if (localName != null)
1785 itemPath = string.Format(CultureInfo.InvariantCulture, xPathNamedItemSubFormatString, localName, nameValue);
1787 Fx.Assert(rest != null, "GetXPathParameters Method should never set rest to null. this happened for: " + item.GetType());
1788 return documentPath + itemPath + rest;
1791 static void GetXPathParameters(WsdlNS.NamedItem item, out string wsdlNs, out string localName, ref string nameValue, ref string rest)
1793 if (item is WsdlNS.ServiceDescription)
1796 wsdlNs = ((WsdlNS.ServiceDescription)item).TargetNamespace ?? String.Empty;
1798 if (item is WsdlNS.PortType)
1800 localName = "portType";
1801 wsdlNs = ((WsdlNS.PortType)item).ServiceDescription.TargetNamespace ?? String.Empty;
1803 else if (item is WsdlNS.Binding)
1805 localName = "binding";
1806 wsdlNs = ((WsdlNS.Binding)item).ServiceDescription.TargetNamespace ?? String.Empty;
1808 else if (item is WsdlNS.ServiceDescription)
1810 localName = "definitions";
1811 wsdlNs = ((WsdlNS.ServiceDescription)item).TargetNamespace ?? String.Empty;
1813 else if (item is WsdlNS.Service)
1815 localName = "service";
1816 wsdlNs = ((WsdlNS.Service)item).ServiceDescription.TargetNamespace ?? String.Empty;
1818 else if (item is WsdlNS.Message)
1820 localName = "message";
1821 wsdlNs = ((WsdlNS.Message)item).ServiceDescription.TargetNamespace ?? String.Empty;
1823 else if (item is WsdlNS.Port)
1825 WsdlNS.Service wsdlService = ((WsdlNS.Port)item).Service;
1826 localName = "service";
1827 nameValue = wsdlService.Name;
1828 wsdlNs = wsdlService.ServiceDescription.TargetNamespace ?? String.Empty;
1829 rest = string.Format(CultureInfo.InvariantCulture, xPathNamedItemSubFormatString, "port", item.Name);
1831 else if (item is WsdlNS.Operation)
1833 WsdlNS.PortType wsdlPortType = ((WsdlNS.Operation)item).PortType;
1834 localName = "portType";
1835 nameValue = wsdlPortType.Name;
1836 wsdlNs = wsdlPortType.ServiceDescription.TargetNamespace ?? String.Empty;
1837 rest = string.Format(CultureInfo.InvariantCulture, xPathNamedItemSubFormatString, "operation", item.Name);
1839 else if (item is WsdlNS.OperationBinding)
1841 WsdlNS.OperationBinding wsdlOperationBinding = ((WsdlNS.OperationBinding)item);
1842 localName = "binding";
1843 nameValue = wsdlOperationBinding.Binding.Name;
1844 wsdlNs = wsdlOperationBinding.Binding.ServiceDescription.TargetNamespace ?? String.Empty;
1845 rest = string.Format(CultureInfo.InvariantCulture, xPathNamedItemSubFormatString, "operation", item.Name);
1847 else if (item is WsdlNS.MessageBinding)
1849 localName = "binding";
1850 WsdlNS.OperationBinding wsdlOperationBinding = ((WsdlNS.MessageBinding)item).OperationBinding;
1851 wsdlNs = wsdlOperationBinding.Binding.ServiceDescription.TargetNamespace ?? String.Empty;
1852 nameValue = wsdlOperationBinding.Binding.Name;
1853 string messageName = item.Name;
1855 string messageTag = string.Empty;
1856 if (item is WsdlNS.InputBinding)
1857 messageTag = "input";
1858 else if (item is WsdlNS.OutputBinding)
1859 messageTag = "output";
1860 else if (item is WsdlNS.FaultBinding)
1861 messageTag = "fault";
1863 Fx.Assert("Unsupported WSDL OM: unknown WsdlNS.MessageBinding: " + item.GetType());
1865 rest = string.Format(CultureInfo.InvariantCulture, xPathNamedItemSubFormatString, "operation", wsdlOperationBinding.Name);
1866 if (string.IsNullOrEmpty(messageName))
1867 rest += string.Format(CultureInfo.InvariantCulture, xPathItemSubFormatString, messageTag);
1869 rest += string.Format(CultureInfo.InvariantCulture, xPathNamedItemSubFormatString, messageTag, messageName);
1873 Fx.Assert("GetXPathParameters Method should be updated to support " + item.GetType());
1879 void LogImportWarning(string warningMessage)
1881 if (warnings.ContainsKey(warningMessage))
1883 if (warnings.Count >= 1024)
1885 warnings.Add(warningMessage, warningMessage);
1886 this.Errors.Add(new MetadataConversionError(warningMessage, true));
1889 void LogImportError(WsdlNS.NamedItem item, WsdlImportException wie)
1891 string errormessage;
1892 if (wie.InnerException != null && (wie.InnerException is WsdlImportException))
1894 WsdlImportException wieInner = wie.InnerException as WsdlImportException;
1895 string dependencyMessage = SR.GetString(SR.WsdlImportErrorDependencyDetail, GetElementName(wieInner.SourceItem), GetElementName(item), CreateXPathString(wieInner.SourceItem));
1896 errormessage = SR.GetString(SR.WsdlImportErrorMessageDetail, GetElementName(item), CreateXPathString(wie.SourceItem), dependencyMessage);
1900 errormessage = SR.GetString(SR.WsdlImportErrorMessageDetail, GetElementName(item), CreateXPathString(wie.SourceItem), wie.Message);
1903 importErrors.Add(item, wie);
1904 this.Errors.Add(new MetadataConversionError(errormessage, false));
1907 static Exception CreateBeforeImportExtensionException(IWsdlImportExtension importer, Exception e)
1909 string errorMessage = SR.GetString(SR.WsdlExtensionBeforeImportError, importer.GetType().AssemblyQualifiedName, e.Message);
1910 return new InvalidOperationException(errorMessage, e);
1913 Exception CreateAlreadyFaultedException(WsdlNS.NamedItem item)
1915 WsdlImportException innerException = importErrors[item];
1916 string warningMsg = SR.GetString(SR.WsdlItemAlreadyFaulted, GetElementName(item));
1917 return new AlreadyFaultedException(warningMsg, innerException);
1920 static Exception CreateExtensionException(IWsdlImportExtension importer, Exception e)
1922 string errorMessage = SR.GetString(SR.WsdlExtensionImportError, importer.GetType().FullName, e.Message);
1923 //consider Microsoft, allow internal exceptions to throw WsdlImportException and handle it in some special way?
1924 return new InvalidOperationException(errorMessage, e);
1927 class AlreadyFaultedException : InvalidOperationException
1929 internal AlreadyFaultedException(string message, WsdlImportException innerException)
1930 : base(message, innerException) { }
1933 class WsdlImportException : Exception
1935 WsdlNS.NamedItem sourceItem;
1936 readonly string xPath = null;
1938 WsdlImportException(WsdlNS.NamedItem item, Exception innerException)
1939 : base(string.Empty, innerException)
1941 this.xPath = CreateXPathString(item);
1942 this.sourceItem = item;
1945 internal static WsdlImportException Create(WsdlNS.NamedItem item, Exception innerException)
1947 WsdlImportException wie = innerException as WsdlImportException;
1948 if (wie != null && wie.IsChildNodeOf(item))
1950 wie.sourceItem = item;
1955 AlreadyFaultedException afe = innerException as AlreadyFaultedException;
1957 return new WsdlImportException(item, afe.InnerException);
1959 return new WsdlImportException(item, innerException);
1963 internal bool IsChildNodeOf(WsdlNS.NamedItem item)
1965 return this.XPath.StartsWith(CreateXPathString(item), StringComparison.Ordinal);
1968 internal string XPath { get { return xPath; } }
1970 internal WsdlNS.NamedItem SourceItem { get { return sourceItem; } }
1972 public override string Message
1976 Exception messageException = this.InnerException;
1978 while (messageException is WsdlImportException)
1979 messageException = messageException.InnerException;
1981 if (messageException == null)
1982 return string.Empty;
1984 return messageException.Message;
1989 internal class WsdlPolicyReader
1991 WsdlImporter importer;
1992 WsdlPolicyDictionary policyDictionary;
1994 static readonly string[] EmptyStringArray = new string[0];
1996 internal WsdlPolicyReader(WsdlImporter importer)
1998 this.importer = importer;
1999 this.policyDictionary = new WsdlPolicyDictionary(importer);
2000 importer.PolicyWarningOccured += this.LogPolicyNormalizationWarning;
2003 IEnumerable<IEnumerable<XmlElement>> GetPolicyAlternatives(WsdlNS.NamedItem item, WsdlNS.ServiceDescription wsdl)
2005 Collection<XmlElement> policyElements = new Collection<XmlElement>();
2007 foreach (XmlElement element in GetReferencedPolicy(item, wsdl))
2009 policyElements.Add(element);
2012 foreach (XmlElement element in GetEmbeddedPolicy(item))
2014 policyElements.Add(element);
2015 if (!policyDictionary.PolicySourceTable.ContainsKey(element))
2016 policyDictionary.PolicySourceTable.Add(element, wsdl);
2019 return importer.NormalizePolicy(policyElements);
2022 void LogPolicyNormalizationWarning(XmlElement contextAssertion, string warningMessage)
2024 string xPath = null;
2025 if (contextAssertion != null)
2026 xPath = this.policyDictionary.CreateIdXPath(contextAssertion);
2028 StringBuilder warningMsg = new StringBuilder();
2029 warningMsg.AppendLine(warningMessage);
2031 if (!string.IsNullOrEmpty(xPath))
2033 warningMsg.AppendLine(SR.GetString(SR.XPathPointer, xPath));
2038 // We were given a context assertion that we couldn't get an XPath for
2040 warningMsg.AppendLine(SR.GetString(SR.XPathPointer, SR.GetString(SR.XPathUnavailable)));
2042 importer.LogImportWarning(warningMsg.ToString());
2045 internal static bool ContainsPolicy(WsdlNS.Binding wsdlBinding)
2047 if (HasPolicyAttached(wsdlBinding))
2050 foreach (WsdlNS.OperationBinding wsdlOperationBinding in wsdlBinding.Operations)
2052 if (HasPolicyAttached(wsdlOperationBinding))
2056 if (wsdlOperationBinding.Input != null && HasPolicyAttached(wsdlOperationBinding.Input))
2060 if (wsdlOperationBinding.Output != null && HasPolicyAttached(wsdlOperationBinding.Output))
2064 foreach (WsdlNS.FaultBinding faultBinding in wsdlOperationBinding.Faults)
2066 if (HasPolicyAttached(faultBinding))
2076 internal static bool HasPolicy(WsdlNS.Port wsdlPort)
2078 return HasPolicyAttached(wsdlPort);
2081 internal static IEnumerable<XmlElement> GetEmbeddedPolicy(WsdlNS.NamedItem item)
2083 List<XmlElement> embeddedPolicies = new List<XmlElement>();
2084 embeddedPolicies.AddRange(item.Extensions.FindAll(MetadataStrings.WSPolicy.Elements.Policy,
2085 MetadataStrings.WSPolicy.NamespaceUri));
2086 embeddedPolicies.AddRange(item.Extensions.FindAll(MetadataStrings.WSPolicy.Elements.Policy,
2087 MetadataStrings.WSPolicy.NamespaceUri15));
2088 return embeddedPolicies;
2091 IEnumerable<XmlElement> GetReferencedPolicy(WsdlNS.NamedItem item, WsdlNS.ServiceDescription wsdl)
2093 string xPath = CreateXPathString(item);
2095 foreach (string policyRef in GetPolicyReferenceUris(item, xPath))
2097 XmlElement policy = policyDictionary.ResolvePolicyReference(policyRef, wsdl);
2100 StringBuilder warningMsg = new StringBuilder();
2101 warningMsg.AppendLine(SR.GetString(SR.UnableToFindPolicyWithId, policyRef));
2102 warningMsg.AppendLine(SR.GetString(SR.XPathPointer, xPath));
2103 importer.LogImportWarning(warningMsg.ToString());
2106 yield return policy;
2110 IEnumerable<string> GetPolicyReferenceUris(WsdlNS.NamedItem item, string xPath)
2113 // get policy from wsp:PolicyUris attribute
2115 foreach (string policyUri in ReadPolicyUrisAttribute(item))
2116 yield return policyUri;
2119 // get policy from <wsp:PolicyReference> Elements
2121 foreach (string policyUri in ReadPolicyReferenceElements(item, xPath))
2122 yield return policyUri;
2125 IEnumerable<string> ReadPolicyReferenceElements(WsdlNS.NamedItem item, string xPath)
2127 List<XmlElement> policyReferences = new List<XmlElement>();
2128 policyReferences.AddRange(item.Extensions.FindAll(MetadataStrings.WSPolicy.Elements.PolicyReference,
2129 MetadataStrings.WSPolicy.NamespaceUri));
2130 policyReferences.AddRange(item.Extensions.FindAll(MetadataStrings.WSPolicy.Elements.PolicyReference,
2131 MetadataStrings.WSPolicy.NamespaceUri15));
2133 foreach (XmlElement element in policyReferences)
2135 string idRef = element.GetAttribute(MetadataStrings.WSPolicy.Attributes.URI);
2139 string warningMsg = SR.GetString(SR.PolicyReferenceMissingURI, MetadataStrings.WSPolicy.Attributes.URI);
2140 importer.LogImportWarning(warningMsg);
2142 else if (idRef == string.Empty)
2144 string warningMsg = SR.GetString(SR.PolicyReferenceInvalidId);
2145 importer.LogImportWarning(warningMsg);
2155 static string[] ReadPolicyUrisAttribute(WsdlNS.NamedItem item)
2158 XmlAttribute[] attributes = item.ExtensibleAttributes;
2159 if (attributes != null && attributes.Length > 0)
2161 foreach (XmlAttribute attribute in attributes)
2163 if (PolicyHelper.IsPolicyURIs(attribute))
2165 return attribute.Value.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
2170 return EmptyStringArray;
2173 static bool HasPolicyAttached(WsdlNS.NamedItem item)
2175 XmlAttribute[] attributes = item.ExtensibleAttributes;
2176 if (attributes != null && Array.Exists(attributes, PolicyHelper.IsPolicyURIs))
2181 if (item.Extensions.Find(MetadataStrings.WSPolicy.Elements.PolicyReference, MetadataStrings.WSPolicy.NamespaceUri) != null
2182 || item.Extensions.Find(MetadataStrings.WSPolicy.Elements.PolicyReference, MetadataStrings.WSPolicy.NamespaceUri15) != null)
2187 if (item.Extensions.Find(MetadataStrings.WSPolicy.Elements.Policy, MetadataStrings.WSPolicy.NamespaceUri) != null
2188 || item.Extensions.Find(MetadataStrings.WSPolicy.Elements.Policy, MetadataStrings.WSPolicy.NamespaceUri15) != null)
2196 internal PolicyAlternatives GetPolicyAlternatives(WsdlEndpointConversionContext endpointContext)
2198 PolicyAlternatives policyAlternatives = new PolicyAlternatives();
2201 // Create EndpointAlternatives either from wsd:binding or from CrossProduct of wsd:binding and wsdl:port policy
2203 WsdlNS.ServiceDescription bindingWsdl = endpointContext.WsdlBinding.ServiceDescription;
2204 IEnumerable<IEnumerable<XmlElement>> wsdlBindingAlternatives = this.GetPolicyAlternatives(endpointContext.WsdlBinding, bindingWsdl);
2205 if (endpointContext.WsdlPort != null)
2207 IEnumerable<IEnumerable<XmlElement>> wsdlPortAlternatives = this.GetPolicyAlternatives(endpointContext.WsdlPort, endpointContext.WsdlPort.Service.ServiceDescription);
2208 policyAlternatives.EndpointAlternatives = PolicyHelper.CrossProduct<XmlElement>(wsdlBindingAlternatives, wsdlPortAlternatives, new YieldLimiter(this.importer.Quotas.MaxYields, this.importer));
2212 policyAlternatives.EndpointAlternatives = wsdlBindingAlternatives;
2216 // Create operation and message policy
2218 policyAlternatives.OperationBindingAlternatives = new Dictionary<OperationDescription, IEnumerable<IEnumerable<XmlElement>>>(endpointContext.Endpoint.Contract.Operations.Count);
2219 policyAlternatives.MessageBindingAlternatives = new Dictionary<MessageDescription, IEnumerable<IEnumerable<XmlElement>>>();
2220 policyAlternatives.FaultBindingAlternatives = new Dictionary<FaultDescription, IEnumerable<IEnumerable<XmlElement>>>();
2222 foreach (OperationDescription operation in endpointContext.Endpoint.Contract.Operations)
2224 // Skip operations that have Action/ReplyAction = "*"
2225 if (!WsdlExporter.OperationIsExportable(operation))
2230 WsdlNS.OperationBinding wsdlOperationBinding = endpointContext.GetOperationBinding(operation);
2233 IEnumerable<IEnumerable<XmlElement>> operationAlternatives = this.GetPolicyAlternatives(wsdlOperationBinding, bindingWsdl);
2234 policyAlternatives.OperationBindingAlternatives.Add(operation, operationAlternatives);
2236 foreach (MessageDescription message in operation.Messages)
2238 WsdlNS.MessageBinding wsdlMessageBinding = endpointContext.GetMessageBinding(message);
2239 CreateMessageBindingAlternatives(policyAlternatives, bindingWsdl, message, wsdlMessageBinding);
2242 foreach (FaultDescription fault in operation.Faults)
2244 WsdlNS.FaultBinding wsdlFaultBinding = endpointContext.GetFaultBinding(fault);
2245 CreateFaultBindingAlternatives(policyAlternatives, bindingWsdl, fault, wsdlFaultBinding);
2248 #pragma warning suppress 56500 // covered by FxCOP
2253 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(wsdlOperationBinding, e));
2257 return policyAlternatives;
2260 void CreateMessageBindingAlternatives(PolicyAlternatives policyAlternatives, WsdlNS.ServiceDescription bindingWsdl, MessageDescription message, WsdlNS.MessageBinding wsdlMessageBinding)
2264 IEnumerable<IEnumerable<XmlElement>> messageAlternatives = this.GetPolicyAlternatives(wsdlMessageBinding, bindingWsdl);
2265 policyAlternatives.MessageBindingAlternatives.Add(message, messageAlternatives);
2267 #pragma warning suppress 56500 // covered by FxCOP
2272 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(wsdlMessageBinding, e));
2276 void CreateFaultBindingAlternatives(PolicyAlternatives policyAlternatives, WsdlNS.ServiceDescription bindingWsdl, FaultDescription fault, WsdlNS.FaultBinding wsdlFaultBinding)
2280 IEnumerable<IEnumerable<XmlElement>> faultAlternatives = this.GetPolicyAlternatives(wsdlFaultBinding, bindingWsdl);
2281 policyAlternatives.FaultBindingAlternatives.Add(fault, faultAlternatives);
2283 #pragma warning suppress 56500 // covered by FxCOP
2288 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsdlImportException.Create(wsdlFaultBinding, e));
2292 internal XmlElement ResolvePolicyReference(string policyReference, XmlElement contextPolicyAssertion)
2294 return this.policyDictionary.ResolvePolicyReference(policyReference, contextPolicyAssertion);
2297 class WsdlPolicyDictionary
2299 readonly MetadataImporter importer;
2300 readonly Dictionary<WsdlNS.ServiceDescription, Dictionary<string, XmlElement>> embeddedPolicyDictionary = new Dictionary<WsdlNS.ServiceDescription, Dictionary<string, XmlElement>>();
2301 readonly Dictionary<string, XmlElement> externalPolicyDictionary = new Dictionary<string, XmlElement>();
2302 readonly Dictionary<XmlElement, WsdlNS.ServiceDescription> policySourceTable = new Dictionary<XmlElement, WsdlNS.ServiceDescription>();
2304 internal Dictionary<XmlElement, WsdlNS.ServiceDescription> PolicySourceTable
2306 get { return policySourceTable; }
2309 internal WsdlPolicyDictionary(WsdlImporter importer)
2311 this.importer = importer;
2314 // Embedded Policy documents
2316 foreach (WsdlNS.ServiceDescription wsdl in importer.wsdlDocuments)
2318 foreach (XmlElement element in WsdlPolicyReader.GetEmbeddedPolicy(wsdl))
2320 AddEmbeddedPolicy(importer, wsdl, element);
2325 // External Policy documents
2327 foreach (KeyValuePair<string, XmlElement> policyDocument in importer.policyDocuments)
2329 AddExternalPolicy(importer, policyDocument);
2334 void AddEmbeddedPolicy(WsdlImporter importer, WsdlNS.ServiceDescription wsdl, XmlElement element)
2336 string key = GetFragmentIdentifier(element);
2337 if (String.IsNullOrEmpty(key))
2339 string xPath = CreateXPathString(wsdl);
2340 string warningMsg = SR.GetString(SR.PolicyInWsdlMustHaveFragmentId, xPath);
2341 importer.LogImportWarning(warningMsg);
2345 Dictionary<string, XmlElement> wsdlPolicyDictionary;
2346 if (!this.embeddedPolicyDictionary.TryGetValue(wsdl, out wsdlPolicyDictionary))
2348 wsdlPolicyDictionary = new Dictionary<string, XmlElement>();
2349 this.embeddedPolicyDictionary.Add(wsdl, wsdlPolicyDictionary);
2351 else if (wsdlPolicyDictionary.ContainsKey(key))
2353 string xPath = CreateIdXPath(wsdl, element, key);
2354 string warningMsg = SR.GetString(SR.DuplicatePolicyInWsdlSkipped, xPath);
2355 importer.LogImportWarning(warningMsg);
2359 wsdlPolicyDictionary.Add(key, element);
2360 policySourceTable.Add(element, wsdl);
2363 void AddExternalPolicy(WsdlImporter importer, KeyValuePair<string, XmlElement> policyDocument)
2365 if (policyDocument.Value.NamespaceURI != MetadataStrings.WSPolicy.NamespaceUri
2366 && policyDocument.Value.NamespaceURI != MetadataStrings.WSPolicy.NamespaceUri15)
2368 string warningMsg = SR.GetString(SR.UnrecognizedPolicyDocumentNamespace, policyDocument.Value.NamespaceURI);
2369 importer.LogImportWarning(warningMsg);
2373 if (PolicyHelper.GetNodeType(policyDocument.Value) != PolicyHelper.NodeType.Policy)
2375 string warningMsg = SR.GetString(SR.UnsupportedPolicyDocumentRoot, policyDocument.Value.Name);
2376 importer.LogImportWarning(warningMsg);
2380 string key = CreateKeyFromPolicy(policyDocument.Key, policyDocument.Value);
2381 if (externalPolicyDictionary.ContainsKey(key))
2383 string warningMsg = SR.GetString(SR.DuplicatePolicyDocumentSkipped, key);
2384 importer.LogImportWarning(warningMsg);
2388 this.externalPolicyDictionary.Add(key, policyDocument.Value);
2391 internal XmlElement ResolvePolicyReference(string policyReference, XmlElement contextPolicyAssertion)
2395 if (policyReference[0] != '#')
2397 externalPolicyDictionary.TryGetValue(policyReference, out policy);
2401 if (contextPolicyAssertion == null)
2406 WsdlNS.ServiceDescription sourceWsdl;
2407 if (!policySourceTable.TryGetValue(contextPolicyAssertion, out sourceWsdl))
2412 return ResolvePolicyReference(policyReference, sourceWsdl);
2415 internal XmlElement ResolvePolicyReference(string policyReference, WsdlNS.ServiceDescription wsdlDocument)
2418 if (policyReference[0] != '#')
2420 externalPolicyDictionary.TryGetValue(policyReference, out policy);
2424 Dictionary<string, XmlElement> wsdlPolicyDictionary;
2425 if (!this.embeddedPolicyDictionary.TryGetValue(wsdlDocument, out wsdlPolicyDictionary))
2430 wsdlPolicyDictionary.TryGetValue(policyReference, out policy);
2434 static string CreateKeyFromPolicy(string identifier, XmlElement policyElement)
2436 string policyId = GetFragmentIdentifier(policyElement);
2437 string policyUri = string.Format(CultureInfo.InvariantCulture, "{0}{1}", identifier, policyId);
2441 static string GetFragmentIdentifier(XmlElement element)
2443 return PolicyHelper.GetFragmentIdentifier(element);
2446 static readonly string wspPolicy = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", MetadataStrings.WSPolicy.Prefix, MetadataStrings.WSPolicy.Elements.Policy);
2447 static readonly string xmlId = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", MetadataStrings.Xml.Prefix, MetadataStrings.Xml.Attributes.Id);
2448 static readonly string wsuId = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", MetadataStrings.Wsu.Prefix, MetadataStrings.Wsu.Attributes.Id);
2450 internal string CreateIdXPath(XmlElement policyAssertion)
2452 WsdlNS.ServiceDescription sourceWsdl;
2453 if (!policySourceTable.TryGetValue(policyAssertion, out sourceWsdl))
2457 string key = GetFragmentIdentifier(policyAssertion);
2458 if (string.IsNullOrEmpty(key))
2462 return CreateIdXPath(sourceWsdl, policyAssertion, key);
2465 internal static string CreateIdXPath(WsdlNS.ServiceDescription wsdl, XmlElement element, string key)
2467 string xPath = CreateXPathString(wsdl);
2470 if (element.HasAttribute(MetadataStrings.Wsu.Attributes.Id, MetadataStrings.Wsu.NamespaceUri))
2474 else if (element.HasAttribute(MetadataStrings.Xml.Attributes.Id, MetadataStrings.Xml.NamespaceUri))
2480 Fx.Assert("CreateIdXPath always called with a valid key");
2483 return string.Format(CultureInfo.InvariantCulture, "{0}/{1}/[@{2}='{3}']", xPath, wspPolicy, idAttrib, key);
2493 DoNotThrowExceptions,
2496 enum WsdlPortTypeImportOptions
2498 ReuseExistingContracts,
2499 IgnoreExistingContracts,