| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Globalization; |
| | | 7 | | using System.IO; |
| | | 8 | | using System.Linq; |
| | | 9 | | using System.Xml; |
| | | 10 | | using System.Xml.Schema; |
| | | 11 | | using System.Xml.Serialization; |
| | | 12 | | using CoreWCF.Channels; |
| | | 13 | | using CoreWCF.Runtime; |
| | | 14 | | using WsdlNS = System.Web.Services.Description; |
| | | 15 | | |
| | | 16 | | namespace CoreWCF.Description |
| | | 17 | | { |
| | | 18 | | public class WsdlExporter : MetadataExporter |
| | | 19 | | { |
| | | 20 | | internal const string SessionOpenedAction = "http://schemas.microsoft.com/2011/02/session/onopen"; |
| | | 21 | | internal const string DefaultNamespace = "http://tempuri.org/"; |
| | | 22 | | internal const string DefaultServiceName = "service"; |
| | | 23 | | private static XmlDocument s_xmlDocument; |
| | | 24 | | private bool _isFaulted = false; |
| | 47 | 25 | | private Dictionary<ContractDescription, WsdlContractConversionContext> _exportedContracts = new Dictionary<Contr |
| | 47 | 26 | | private Dictionary<BindingDictionaryKey, WsdlEndpointConversionContext> _exportedBindings = new Dictionary<Bindi |
| | 47 | 27 | | private Dictionary<EndpointDictionaryKey, ServiceEndpoint> _exportedEndpoints = new Dictionary<EndpointDictionar |
| | | 28 | | |
| | | 29 | | internal WsdlExporter Clone() |
| | | 30 | | { |
| | 24 | 31 | | WsdlExporter exporter = new WsdlExporter(); |
| | | 32 | | |
| | 24 | 33 | | if (_exportedContracts.Count > 0) |
| | 0 | 34 | | exporter._exportedContracts = new Dictionary<ContractDescription, WsdlContractConversionContext>(_export |
| | | 35 | | |
| | 24 | 36 | | if (_exportedBindings.Count > 0) |
| | 0 | 37 | | exporter._exportedBindings = new Dictionary<BindingDictionaryKey, WsdlEndpointConversionContext>(_export |
| | | 38 | | |
| | 24 | 39 | | if (_exportedEndpoints.Count > 0) |
| | 0 | 40 | | exporter._exportedEndpoints = new Dictionary<EndpointDictionaryKey, ServiceEndpoint>(_exportedEndpoints) |
| | | 41 | | |
| | 24 | 42 | | exporter._isFaulted = _isFaulted; |
| | | 43 | | |
| | | 44 | | // Base class clone |
| | 24 | 45 | | exporter.PolicyVersion = PolicyVersion; |
| | 48 | 46 | | foreach (var error in Errors) |
| | 0 | 47 | | exporter.Errors.Add(error); |
| | | 48 | | |
| | 48 | 49 | | foreach(var stateItem in State) |
| | 0 | 50 | | exporter.State.Add(stateItem.Key, stateItem.Value); |
| | | 51 | | |
| | 24 | 52 | | return exporter; |
| | | 53 | | } |
| | | 54 | | |
| | | 55 | | public override void ExportContract(ContractDescription contract) |
| | | 56 | | { |
| | 32 | 57 | | if (_isFaulted) |
| | | 58 | | { |
| | 0 | 59 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.WsdlExporterI |
| | | 60 | | } |
| | | 61 | | |
| | 32 | 62 | | if (contract == null) |
| | | 63 | | { |
| | 0 | 64 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(contract)); |
| | | 65 | | } |
| | | 66 | | |
| | 32 | 67 | | if (!_exportedContracts.ContainsKey(contract)) |
| | | 68 | | { |
| | | 69 | | try |
| | | 70 | | { |
| | 24 | 71 | | WsdlNS.PortType wsdlPortType = CreateWsdlPortType(contract); |
| | | 72 | | WsdlContractConversionContext contractContext; |
| | | 73 | | |
| | | 74 | | |
| | 24 | 75 | | contractContext = new WsdlContractConversionContext(contract, wsdlPortType); |
| | | 76 | | |
| | 286 | 77 | | foreach (OperationDescription operation in contract.Operations) |
| | | 78 | | { |
| | 119 | 79 | | if (!OperationIsExportable(operation, out bool isWildcardAction)) |
| | | 80 | | { |
| | 0 | 81 | | string warningMsg = isWildcardAction ? SR.Format(SR.WarnSkippingOperationWithWildcardAction, |
| | 0 | 82 | | : SR.Format(SR.WarnSkippingOperationWithSessionOpenNotificationEnabled, "Action", Sessio |
| | | 83 | | |
| | 0 | 84 | | LogExportWarning(warningMsg); |
| | 0 | 85 | | continue; |
| | | 86 | | } |
| | | 87 | | |
| | 119 | 88 | | WsdlNS.Operation wsdlOperation = CreateWsdlOperation(operation, contract); |
| | 119 | 89 | | wsdlPortType.Operations.Add(wsdlOperation); |
| | | 90 | | |
| | 119 | 91 | | contractContext.AddOperation(operation, wsdlOperation); |
| | | 92 | | |
| | 714 | 93 | | foreach (MessageDescription message in operation.Messages) |
| | | 94 | | { |
| | | 95 | | //Create Operation Message |
| | 238 | 96 | | WsdlNS.OperationMessage wsdlOperationMessage = CreateWsdlOperationMessage(message); |
| | 238 | 97 | | wsdlOperation.Messages.Add(wsdlOperationMessage); |
| | 238 | 98 | | contractContext.AddMessage(message, wsdlOperationMessage); |
| | | 99 | | } |
| | | 100 | | |
| | 238 | 101 | | foreach (FaultDescription fault in operation.Faults) |
| | | 102 | | { |
| | | 103 | | //Create Operation Fault |
| | 0 | 104 | | WsdlNS.OperationFault wsdlOperationFault = CreateWsdlOperationFault(fault); |
| | 0 | 105 | | wsdlOperation.Faults.Add(wsdlOperationFault); |
| | 0 | 106 | | contractContext.AddFault(fault, wsdlOperationFault); |
| | | 107 | | } |
| | | 108 | | } |
| | | 109 | | |
| | 24 | 110 | | CallExportContract(contractContext); |
| | | 111 | | |
| | 24 | 112 | | _exportedContracts.Add(contract, contractContext); |
| | 24 | 113 | | } |
| | 0 | 114 | | catch |
| | | 115 | | { |
| | 0 | 116 | | _isFaulted = true; |
| | 0 | 117 | | throw; |
| | | 118 | | } |
| | | 119 | | } |
| | 32 | 120 | | } |
| | | 121 | | |
| | | 122 | | public override void ExportEndpoint(ServiceEndpoint endpoint) |
| | | 123 | | { |
| | 0 | 124 | | if (_isFaulted) |
| | | 125 | | { |
| | 0 | 126 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.WsdlExporterI |
| | | 127 | | } |
| | | 128 | | |
| | 0 | 129 | | if (endpoint == null) |
| | | 130 | | { |
| | 0 | 131 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(endpoint)); |
| | | 132 | | } |
| | | 133 | | |
| | 0 | 134 | | ExportEndpoint(endpoint, new XmlQualifiedName(DefaultServiceName, DefaultNamespace), null); |
| | 0 | 135 | | } |
| | | 136 | | |
| | 0 | 137 | | public void ExportEndpoints(IEnumerable<ServiceEndpoint> endpoints, XmlQualifiedName wsdlServiceQName) => Export |
| | | 138 | | |
| | | 139 | | internal void ExportEndpoints(IEnumerable<ServiceEndpoint> endpoints, XmlQualifiedName wsdlServiceQName, Binding |
| | | 140 | | { |
| | 24 | 141 | | if (_isFaulted) |
| | | 142 | | { |
| | 0 | 143 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.WsdlExporterI |
| | | 144 | | } |
| | | 145 | | |
| | 24 | 146 | | if (endpoints == null) |
| | | 147 | | { |
| | 0 | 148 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(endpoints)); |
| | | 149 | | } |
| | | 150 | | |
| | 24 | 151 | | if (wsdlServiceQName == null) |
| | | 152 | | { |
| | 0 | 153 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(wsdlServiceQName)); |
| | | 154 | | } |
| | | 155 | | |
| | 112 | 156 | | foreach (ServiceEndpoint endpoint in endpoints) |
| | | 157 | | { |
| | 32 | 158 | | ExportEndpoint(endpoint, wsdlServiceQName, bindingParameters); |
| | | 159 | | } |
| | 24 | 160 | | } |
| | | 161 | | |
| | | 162 | | public override MetadataSet GetGeneratedMetadata() |
| | | 163 | | { |
| | 24 | 164 | | MetadataSet set = new MetadataSet(); |
| | | 165 | | |
| | 96 | 166 | | foreach (WsdlNS.ServiceDescription wsdl in GeneratedWsdlDocuments) |
| | | 167 | | { |
| | 24 | 168 | | set.MetadataSections.Add(MetadataSection.CreateFromServiceDescription(wsdl)); |
| | | 169 | | } |
| | | 170 | | |
| | 190 | 171 | | foreach (XmlSchema schema in GeneratedXmlSchemas.Schemas()) |
| | | 172 | | { |
| | 71 | 173 | | set.MetadataSections.Add(MetadataSection.CreateFromSchema(schema)); |
| | | 174 | | } |
| | | 175 | | |
| | 24 | 176 | | return set; |
| | | 177 | | } |
| | | 178 | | |
| | 210 | 179 | | public WsdlNS.ServiceDescriptionCollection GeneratedWsdlDocuments { get; } = new WsdlNS.ServiceDescriptionCollec |
| | | 180 | | |
| | 4676 | 181 | | public XmlSchemaSet GeneratedXmlSchemas { get; } = GetEmptySchemaSet(); |
| | | 182 | | |
| | | 183 | | private void ExportEndpoint(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName, BindingParameterCollect |
| | | 184 | | { |
| | 32 | 185 | | if (endpoint.Binding == null) |
| | | 186 | | { |
| | 0 | 187 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.EndpointsMu |
| | | 188 | | } |
| | | 189 | | |
| | 32 | 190 | | EndpointDictionaryKey endpointKey = new EndpointDictionaryKey(endpoint, wsdlServiceQName); |
| | | 191 | | |
| | | 192 | | try |
| | | 193 | | { |
| | 32 | 194 | | if (_exportedEndpoints.ContainsKey(endpointKey)) |
| | | 195 | | { |
| | 0 | 196 | | return; |
| | | 197 | | } |
| | | 198 | | |
| | 32 | 199 | | ExportContract(endpoint.Contract); |
| | | 200 | | |
| | | 201 | | // Retreive Conversion Context for Contract; |
| | | 202 | | // Note: Contract must have already been exported at this point. |
| | 32 | 203 | | WsdlContractConversionContext contractContext = _exportedContracts[endpoint.Contract]; |
| | | 204 | | |
| | | 205 | | |
| | | 206 | | WsdlNS.Binding wsdlBinding; |
| | 32 | 207 | | wsdlBinding = CreateWsdlBindingAndPort(endpoint, wsdlServiceQName, out WsdlNS.Port wsdlPort, out bool ne |
| | | 208 | | |
| | | 209 | | |
| | 32 | 210 | | if (!newWsdlBinding && wsdlPort == null) |
| | | 211 | | { |
| | 0 | 212 | | return; |
| | | 213 | | } |
| | | 214 | | |
| | | 215 | | // Create an Endpoint conversion context based on |
| | | 216 | | // the contract's conversion context (reuse contract correlation information) |
| | | 217 | | WsdlEndpointConversionContext endpointContext; |
| | 32 | 218 | | if (newWsdlBinding) |
| | | 219 | | { |
| | 32 | 220 | | endpointContext = new WsdlEndpointConversionContext(contractContext, endpoint, wsdlBinding, wsdlPort |
| | | 221 | | |
| | 382 | 222 | | foreach (OperationDescription operation in endpoint.Contract.Operations) |
| | | 223 | | { |
| | 159 | 224 | | if (!OperationIsExportable(operation)) |
| | | 225 | | { |
| | | 226 | | continue; |
| | | 227 | | } |
| | | 228 | | |
| | 159 | 229 | | WsdlNS.OperationBinding wsdlOperationBinding = CreateWsdlOperationBinding(operation); |
| | 159 | 230 | | wsdlBinding.Operations.Add(wsdlOperationBinding); |
| | | 231 | | |
| | 159 | 232 | | endpointContext.AddOperationBinding(operation, wsdlOperationBinding); |
| | | 233 | | |
| | 954 | 234 | | foreach (MessageDescription message in operation.Messages) |
| | | 235 | | { |
| | 318 | 236 | | WsdlNS.MessageBinding wsdlMessageBinding = CreateWsdlMessageBinding(message, wsdlOperationBi |
| | 318 | 237 | | endpointContext.AddMessageBinding(message, wsdlMessageBinding); |
| | | 238 | | } |
| | | 239 | | |
| | 318 | 240 | | foreach (FaultDescription fault in operation.Faults) |
| | | 241 | | { |
| | 0 | 242 | | WsdlNS.FaultBinding wsdlFaultBinding = CreateWsdlFaultBinding(fault, wsdlOperationBinding); |
| | 0 | 243 | | endpointContext.AddFaultBinding(fault, wsdlFaultBinding); |
| | | 244 | | } |
| | | 245 | | } |
| | | 246 | | |
| | | 247 | | // CSDMain 180381: Added internal functionality for passing BindingParameters into the ExportPolicy |
| | | 248 | | // However, in order to not change existing behavior, we only call the internal ExportPolicy method |
| | | 249 | | // (non-null binding parameters can only be passed in via internal code paths). Otherwise, we call |
| | | 250 | | PolicyConversionContext policyContext; |
| | 32 | 251 | | if (bindingParameters == null) |
| | | 252 | | { |
| | 0 | 253 | | policyContext = ExportPolicy(endpoint); |
| | | 254 | | } |
| | | 255 | | else |
| | | 256 | | { |
| | 32 | 257 | | policyContext = ExportPolicy(endpoint, bindingParameters); |
| | | 258 | | } |
| | | 259 | | // consider factoring this out of wsdl exporter |
| | 32 | 260 | | new WSPolicyAttachmentHelper(PolicyVersion).AttachPolicy(endpoint, endpointContext, policyContext); |
| | 32 | 261 | | _exportedBindings.Add(new BindingDictionaryKey(endpoint.Contract, endpoint.Binding), endpointContext |
| | | 262 | | } |
| | | 263 | | else |
| | | 264 | | { |
| | 0 | 265 | | endpointContext = new WsdlEndpointConversionContext(_exportedBindings[new BindingDictionaryKey(endpo |
| | | 266 | | } |
| | | 267 | | |
| | 32 | 268 | | CallExportEndpoint(endpointContext); |
| | 32 | 269 | | _exportedEndpoints.Add(endpointKey, endpoint); |
| | 32 | 270 | | if (bindingNameWasUniquified) |
| | | 271 | | { |
| | 8 | 272 | | Errors.Add(new MetadataConversionError(SR.Format(SR.WarnDuplicateBindingQNameNameOnExport, endpoint. |
| | | 273 | | } |
| | 32 | 274 | | } |
| | 0 | 275 | | catch |
| | | 276 | | { |
| | 0 | 277 | | _isFaulted = true; |
| | 0 | 278 | | throw; |
| | | 279 | | } |
| | 32 | 280 | | } |
| | | 281 | | |
| | 41 | 282 | | public static void AddWSAddressingAssertion(MetadataExporter exporter, PolicyConversionContext context, Addressi |
| | | 283 | | |
| | | 284 | | private void CallExportEndpoint(WsdlEndpointConversionContext endpointContext) |
| | | 285 | | { |
| | 510 | 286 | | foreach (IWsdlExportExtension extension in endpointContext.ExportExtensions) |
| | | 287 | | { |
| | 223 | 288 | | CallExtension(endpointContext, extension); |
| | | 289 | | } |
| | 32 | 290 | | } |
| | | 291 | | |
| | | 292 | | private void CallExportContract(WsdlContractConversionContext contractContext) |
| | | 293 | | { |
| | 286 | 294 | | foreach (IWsdlExportExtension extension in contractContext.ExportExtensions) |
| | | 295 | | { |
| | 119 | 296 | | CallExtension(contractContext, extension); |
| | | 297 | | } |
| | 24 | 298 | | } |
| | | 299 | | |
| | | 300 | | private WsdlNS.PortType CreateWsdlPortType(ContractDescription contract) |
| | | 301 | | { |
| | 24 | 302 | | XmlQualifiedName wsdlPortTypeQName = WsdlNamingHelper.GetPortTypeQName(contract); |
| | | 303 | | |
| | 24 | 304 | | WsdlNS.ServiceDescription wsdl = GetOrCreateWsdl(wsdlPortTypeQName.Namespace); |
| | 24 | 305 | | WsdlNS.PortType wsdlPortType = new WsdlNS.PortType |
| | 24 | 306 | | { |
| | 24 | 307 | | Name = wsdlPortTypeQName.Name |
| | 24 | 308 | | }; |
| | 24 | 309 | | if (wsdl.PortTypes[wsdlPortType.Name] != null) |
| | | 310 | | { |
| | 0 | 311 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.DuplicateCo |
| | | 312 | | } |
| | | 313 | | |
| | 24 | 314 | | NetSessionHelper.AddUsingSessionAttributeIfNeeded(wsdlPortType, contract); |
| | 24 | 315 | | wsdl.PortTypes.Add(wsdlPortType); |
| | | 316 | | |
| | 24 | 317 | | return wsdlPortType; |
| | | 318 | | } |
| | | 319 | | |
| | | 320 | | private WsdlNS.Operation CreateWsdlOperation(OperationDescription operation, ContractDescription contract) |
| | | 321 | | { |
| | 119 | 322 | | WsdlNS.Operation wsdlOperation = new WsdlNS.Operation |
| | 119 | 323 | | { |
| | 119 | 324 | | Name = WsdlNamingHelper.GetWsdlOperationName(operation) |
| | 119 | 325 | | }; |
| | 119 | 326 | | NetSessionHelper.AddInitiatingTerminatingAttributesIfNeeded(wsdlOperation, operation, contract); |
| | 119 | 327 | | return wsdlOperation; |
| | | 328 | | } |
| | | 329 | | |
| | | 330 | | private WsdlNS.OperationMessage CreateWsdlOperationMessage(MessageDescription message) |
| | | 331 | | { |
| | | 332 | | WsdlNS.OperationMessage wsdlOperationMessage; |
| | | 333 | | |
| | 238 | 334 | | if (message.Direction == MessageDirection.Input) |
| | | 335 | | { |
| | 119 | 336 | | wsdlOperationMessage = new WsdlNS.OperationInput(); |
| | | 337 | | } |
| | | 338 | | else |
| | | 339 | | { |
| | 119 | 340 | | wsdlOperationMessage = new WsdlNS.OperationOutput(); |
| | | 341 | | } |
| | | 342 | | |
| | 238 | 343 | | if (message.MessageType != null) |
| | | 344 | | { |
| | 2 | 345 | | string messageName = NamingHelper.TypeName(message.MessageType); |
| | 2 | 346 | | wsdlOperationMessage.Name = NamingHelper.XmlName(messageName); |
| | | 347 | | } |
| | | 348 | | |
| | | 349 | | // consider factoring this out of wslExporter |
| | 238 | 350 | | WSAddressingHelper.AddActionAttribute(message.Action, wsdlOperationMessage, PolicyVersion); |
| | 238 | 351 | | return wsdlOperationMessage; |
| | | 352 | | } |
| | | 353 | | |
| | | 354 | | private WsdlNS.OperationFault CreateWsdlOperationFault(FaultDescription fault) |
| | | 355 | | { |
| | | 356 | | WsdlNS.OperationFault wsdlOperationFault; |
| | 0 | 357 | | wsdlOperationFault = new WsdlNS.OperationFault |
| | 0 | 358 | | { |
| | 0 | 359 | | // operation fault name must not be empty (FaultDescription checks this) |
| | 0 | 360 | | Name = fault.Name |
| | 0 | 361 | | }; |
| | | 362 | | |
| | | 363 | | // consider factoring this out of wslExporter |
| | 0 | 364 | | WSAddressingHelper.AddActionAttribute(fault.Action, wsdlOperationFault, PolicyVersion); |
| | 0 | 365 | | return wsdlOperationFault; |
| | | 366 | | } |
| | | 367 | | |
| | | 368 | | private WsdlNS.Binding CreateWsdlBindingAndPort(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName, out |
| | | 369 | | { |
| | | 370 | | WsdlNS.ServiceDescription bindingWsdl; |
| | | 371 | | WsdlNS.Binding wsdlBinding; |
| | | 372 | | XmlQualifiedName wsdlBindingQName; |
| | | 373 | | XmlQualifiedName wsdlPortTypeQName; |
| | | 374 | | // There's a change in behavior from NetFx here. On NetFx, for any MessageEncodingBindingElement we |
| | | 375 | | // would call the internal virtual method IsWsdlExportable. This always returned true for all MEBE |
| | | 376 | | // implementations except WebMessageEncodingBindingElement which returned false. For CoreWCF, |
| | | 377 | | // we're not worrying about supressing exporting the wsdl. We'll either not add the relevant |
| | | 378 | | // interface, or we'll make the relevant method be a no-op to achieve the same thing. |
| | | 379 | | // bool printWsdlDeclaration = IsWsdlExportable(endpoint.Binding); |
| | | 380 | | |
| | 32 | 381 | | if (!_exportedBindings.TryGetValue(new BindingDictionaryKey(endpoint.Contract, endpoint.Binding), out WsdlEn |
| | | 382 | | { |
| | 32 | 383 | | wsdlBindingQName = WsdlNamingHelper.GetBindingQName(endpoint, this, out bindingNameWasUniquified); |
| | 32 | 384 | | bindingWsdl = GetOrCreateWsdl(wsdlBindingQName.Namespace); |
| | 32 | 385 | | wsdlBinding = new WsdlNS.Binding { Name = wsdlBindingQName.Name }; |
| | 32 | 386 | | newBinding = true; |
| | 32 | 387 | | WsdlNS.PortType wsdlPortType = _exportedContracts[endpoint.Contract].WsdlPortType; |
| | 32 | 388 | | wsdlPortTypeQName = new XmlQualifiedName(wsdlPortType.Name, wsdlPortType.ServiceDescription.TargetNamesp |
| | 32 | 389 | | wsdlBinding.Type = wsdlPortTypeQName; |
| | 32 | 390 | | bindingWsdl.Bindings.Add(wsdlBinding); |
| | | 391 | | |
| | 32 | 392 | | EnsureWsdlContainsImport(bindingWsdl, wsdlPortTypeQName.Namespace); |
| | | 393 | | } |
| | | 394 | | else |
| | | 395 | | { |
| | 0 | 396 | | wsdlBindingQName = new XmlQualifiedName(bindingConversionContext.WsdlBinding.Name, bindingConversionCont |
| | 0 | 397 | | bindingNameWasUniquified = false; |
| | 0 | 398 | | bindingWsdl = GeneratedWsdlDocuments[wsdlBindingQName.Namespace]; |
| | 0 | 399 | | wsdlBinding = bindingWsdl.Bindings[wsdlBindingQName.Name]; |
| | 0 | 400 | | newBinding = false; |
| | | 401 | | } |
| | | 402 | | |
| | | 403 | | //We can only create a Port if there is an address |
| | 32 | 404 | | if (endpoint.Address != null) |
| | | 405 | | { |
| | 32 | 406 | | WsdlNS.Service wsdlService = GetOrCreateWsdlService(wsdlServiceQName); |
| | 32 | 407 | | wsdlPort = new WsdlNS.Port(); |
| | 32 | 408 | | string wsdlPortName = WsdlNamingHelper.GetPortName(endpoint, wsdlService); |
| | 32 | 409 | | wsdlPort.Name = wsdlPortName; |
| | 32 | 410 | | wsdlPort.Binding = wsdlBindingQName; |
| | 32 | 411 | | WsdlNS.SoapAddressBinding addressBinding = SoapHelper.GetOrCreateSoapAddressBinding(wsdlBinding, wsdlPor |
| | | 412 | | |
| | 32 | 413 | | if (addressBinding != null) |
| | | 414 | | { |
| | 32 | 415 | | addressBinding.Location = endpoint.Address.Uri.AbsoluteUri; |
| | | 416 | | } |
| | | 417 | | |
| | 32 | 418 | | EnsureWsdlContainsImport(wsdlService.ServiceDescription, wsdlBindingQName.Namespace); |
| | 32 | 419 | | wsdlService.Ports.Add(wsdlPort); |
| | | 420 | | } |
| | | 421 | | else |
| | | 422 | | { |
| | 0 | 423 | | wsdlPort = null; |
| | | 424 | | } |
| | | 425 | | |
| | 32 | 426 | | return wsdlBinding; |
| | | 427 | | } |
| | | 428 | | |
| | 0 | 429 | | public static void AddAddressToWsdlPort(WsdlNS.Port wsdlPort, EndpointAddress address, AddressingVersion address |
| | | 430 | | |
| | 159 | 431 | | private WsdlNS.OperationBinding CreateWsdlOperationBinding(OperationDescription operation) => new WsdlNS.Operati |
| | | 432 | | |
| | | 433 | | private WsdlNS.MessageBinding CreateWsdlMessageBinding(MessageDescription messageDescription, WsdlNS.OperationBi |
| | | 434 | | { |
| | | 435 | | WsdlNS.MessageBinding wsdlMessageBinding; |
| | 318 | 436 | | if (messageDescription.Direction == MessageDirection.Input) |
| | | 437 | | { |
| | 159 | 438 | | wsdlOperationBinding.Input = new WsdlNS.InputBinding(); |
| | 159 | 439 | | wsdlMessageBinding = wsdlOperationBinding.Input; |
| | | 440 | | } |
| | | 441 | | else |
| | | 442 | | { |
| | 159 | 443 | | wsdlOperationBinding.Output = new WsdlNS.OutputBinding(); |
| | 159 | 444 | | wsdlMessageBinding = wsdlOperationBinding.Output; |
| | | 445 | | } |
| | | 446 | | |
| | 318 | 447 | | if (messageDescription.MessageType != null) |
| | | 448 | | { |
| | 2 | 449 | | string messageName = NamingHelper.TypeName(messageDescription.MessageType); |
| | 2 | 450 | | wsdlMessageBinding.Name = NamingHelper.XmlName(messageName); |
| | | 451 | | } |
| | | 452 | | |
| | 318 | 453 | | return wsdlMessageBinding; |
| | | 454 | | } |
| | | 455 | | |
| | | 456 | | private WsdlNS.FaultBinding CreateWsdlFaultBinding(FaultDescription faultDescription, WsdlNS.OperationBinding ws |
| | | 457 | | { |
| | 0 | 458 | | WsdlNS.FaultBinding wsdlFaultBinding = new WsdlNS.FaultBinding(); |
| | 0 | 459 | | wsdlOperationBinding.Faults.Add(wsdlFaultBinding); |
| | 0 | 460 | | if (faultDescription.Name != null) |
| | | 461 | | { |
| | 0 | 462 | | wsdlFaultBinding.Name = faultDescription.Name; |
| | | 463 | | } |
| | | 464 | | |
| | 0 | 465 | | return wsdlFaultBinding; |
| | | 466 | | } |
| | | 467 | | |
| | 596 | 468 | | internal static bool OperationIsExportable(OperationDescription operation) => OperationIsExportable(operation, o |
| | | 469 | | |
| | | 470 | | internal static bool OperationIsExportable(OperationDescription operation, out bool isWildcardAction) |
| | | 471 | | { |
| | 715 | 472 | | isWildcardAction = false; |
| | | 473 | | |
| | 715 | 474 | | if (operation.IsSessionOpenNotificationEnabled) |
| | | 475 | | { |
| | 0 | 476 | | return false; |
| | | 477 | | } |
| | | 478 | | |
| | 4290 | 479 | | for (int i = 0; i < operation.Messages.Count; i++) |
| | | 480 | | { |
| | 1430 | 481 | | if (operation.Messages[i].Action == MessageHeaders.WildcardAction) |
| | | 482 | | { |
| | 0 | 483 | | isWildcardAction = true; |
| | 0 | 484 | | return false; |
| | | 485 | | } |
| | | 486 | | } |
| | | 487 | | |
| | 715 | 488 | | return true; |
| | | 489 | | } |
| | | 490 | | |
| | | 491 | | internal static bool IsBuiltInOperationBehavior(IWsdlExportExtension extension) |
| | | 492 | | { |
| | | 493 | | // This is a change in behavior from NetFx due to dcsob.IsBuiltInOperationBehavior not being public. |
| | | 494 | | // In NetFx, a user added dcsob would be treated as not built-in and the default added dcsob would be |
| | | 495 | | // treated as a built in operation. Being build in meant being placed at the end of the list returned |
| | | 496 | | // from WsdlContractConversionContext.ExportExtensions. In CoreWCF, dcsob will always be at the end of |
| | | 497 | | // the list. The same is true of xsob too. |
| | 397 | 498 | | if (extension is DataContractSerializerOperationBehavior || extension is XmlSerializerOperationBehavior) |
| | | 499 | | { |
| | 397 | 500 | | return true; |
| | | 501 | | } |
| | | 502 | | |
| | 0 | 503 | | return false; |
| | | 504 | | } |
| | | 505 | | |
| | | 506 | | private static XmlDocument XmlDoc |
| | | 507 | | { |
| | | 508 | | get |
| | | 509 | | { |
| | 408 | 510 | | if (s_xmlDocument == null) |
| | | 511 | | { |
| | 1 | 512 | | NameTable nameTable = new NameTable(); |
| | 1 | 513 | | nameTable.Add(MetadataStrings.WSPolicy.Elements.Policy); |
| | 1 | 514 | | nameTable.Add(MetadataStrings.WSPolicy.Elements.All); |
| | 1 | 515 | | nameTable.Add(MetadataStrings.WSPolicy.Elements.ExactlyOne); |
| | 1 | 516 | | nameTable.Add(MetadataStrings.WSPolicy.Attributes.PolicyURIs); |
| | 1 | 517 | | nameTable.Add(MetadataStrings.Wsu.Attributes.Id); |
| | 1 | 518 | | nameTable.Add(MetadataStrings.Addressing200408.Policy.UsingAddressing); |
| | 1 | 519 | | nameTable.Add(MetadataStrings.Addressing10.WsdlBindingPolicy.UsingAddressing); |
| | 1 | 520 | | nameTable.Add(MetadataStrings.Addressing10.MetadataPolicy.Addressing); |
| | 1 | 521 | | nameTable.Add(MetadataStrings.Addressing10.MetadataPolicy.AnonymousResponses); |
| | 1 | 522 | | nameTable.Add(MetadataStrings.Addressing10.MetadataPolicy.NonAnonymousResponses); |
| | 1 | 523 | | s_xmlDocument = new XmlDocument(nameTable); |
| | | 524 | | } |
| | | 525 | | |
| | 408 | 526 | | return s_xmlDocument; |
| | | 527 | | } |
| | | 528 | | } |
| | | 529 | | |
| | | 530 | | // Generate WSDL Document if it doesn't already exist otherwise, return the appropriate WSDL document |
| | | 531 | | internal WsdlNS.ServiceDescription GetOrCreateWsdl(string ns) |
| | | 532 | | { |
| | | 533 | | // NOTE: this method is not thread safe |
| | 88 | 534 | | WsdlNS.ServiceDescriptionCollection wsdlCollection = GeneratedWsdlDocuments; |
| | 88 | 535 | | WsdlNS.ServiceDescription wsdl = wsdlCollection[ns]; |
| | | 536 | | |
| | | 537 | | // Look for wsdl in service descriptions that have been created. If we cannot find it then we create it |
| | 88 | 538 | | if (wsdl == null) |
| | | 539 | | { |
| | 24 | 540 | | wsdl = new WsdlNS.ServiceDescription { TargetNamespace = ns }; |
| | 24 | 541 | | XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(new WsdlNamespaceHelper(PolicyVersion). |
| | 24 | 542 | | if (!string.IsNullOrEmpty(wsdl.TargetNamespace)) |
| | | 543 | | { |
| | 24 | 544 | | namespaces.Add("tns", wsdl.TargetNamespace); |
| | | 545 | | } |
| | | 546 | | |
| | 24 | 547 | | wsdl.Namespaces = namespaces; |
| | 24 | 548 | | wsdlCollection.Add(wsdl); |
| | | 549 | | } |
| | | 550 | | |
| | 88 | 551 | | return wsdl; |
| | | 552 | | } |
| | | 553 | | |
| | | 554 | | private WsdlNS.Service GetOrCreateWsdlService(XmlQualifiedName wsdlServiceQName) |
| | | 555 | | { |
| | | 556 | | // NOTE: this method is not thread safe |
| | 32 | 557 | | WsdlNS.ServiceDescription wsdl = GetOrCreateWsdl(wsdlServiceQName.Namespace); |
| | 32 | 558 | | WsdlNS.Service wsdlService = wsdl.Services[wsdlServiceQName.Name]; |
| | 32 | 559 | | if (wsdlService == null) |
| | | 560 | | { |
| | | 561 | | //Service not found. Create service. |
| | 24 | 562 | | wsdlService = new WsdlNS.Service { Name = wsdlServiceQName.Name }; |
| | 24 | 563 | | if (string.IsNullOrEmpty(wsdl.Name)) |
| | | 564 | | { |
| | 24 | 565 | | wsdl.Name = wsdlService.Name; |
| | | 566 | | } |
| | | 567 | | |
| | 24 | 568 | | wsdl.Services.Add(wsdlService); |
| | | 569 | | } |
| | 32 | 570 | | return wsdlService; |
| | | 571 | | } |
| | | 572 | | |
| | | 573 | | private static void EnsureWsdlContainsImport(WsdlNS.ServiceDescription srcWsdl, string target) |
| | | 574 | | { |
| | 64 | 575 | | if (srcWsdl.TargetNamespace == target) |
| | | 576 | | { |
| | 64 | 577 | | return; |
| | | 578 | | } |
| | | 579 | | |
| | | 580 | | // FindImport |
| | 0 | 581 | | foreach (WsdlNS.Import import in srcWsdl.Imports) |
| | | 582 | | { |
| | 0 | 583 | | if (import.Namespace == target) |
| | | 584 | | { |
| | 0 | 585 | | return; |
| | | 586 | | } |
| | | 587 | | } |
| | | 588 | | |
| | | 589 | | { |
| | 0 | 590 | | WsdlNS.Import import = new WsdlNS.Import |
| | 0 | 591 | | { |
| | 0 | 592 | | Location = null, |
| | 0 | 593 | | Namespace = target |
| | 0 | 594 | | }; |
| | 0 | 595 | | srcWsdl.Imports.Add(import); |
| | 0 | 596 | | WsdlNamespaceHelper.FindOrCreatePrefix("i", target, srcWsdl); |
| | 0 | 597 | | return; |
| | | 598 | | } |
| | 0 | 599 | | } |
| | | 600 | | |
| | 0 | 601 | | private void LogExportWarning(string warningMessage) => Errors.Add(new MetadataConversionError(warningMessage, t |
| | | 602 | | |
| | 47 | 603 | | internal static XmlSchemaSet GetEmptySchemaSet() => new XmlSchemaSet { XmlResolver = null }; |
| | | 604 | | |
| | | 605 | | internal static class WSAddressingHelper |
| | | 606 | | { |
| | | 607 | | internal static void AddActionAttribute(string actionUri, WsdlNS.OperationMessage wsdlOperationMessage, Poli |
| | | 608 | | { |
| | | 609 | | XmlAttribute attribute; |
| | 238 | 610 | | if (policyVersion == PolicyVersion.Policy12) |
| | | 611 | | { |
| | 238 | 612 | | attribute = XmlDoc.CreateAttribute(MetadataStrings.AddressingWsdl.Prefix, |
| | 238 | 613 | | MetadataStrings.AddressingWsdl.Action, |
| | 238 | 614 | | MetadataStrings.AddressingWsdl.NamespaceUri); |
| | | 615 | | } |
| | | 616 | | else |
| | | 617 | | { |
| | 0 | 618 | | attribute = XmlDoc.CreateAttribute(MetadataStrings.AddressingMetadata.Prefix, |
| | 0 | 619 | | MetadataStrings.AddressingMetadata.Action, |
| | 0 | 620 | | MetadataStrings.AddressingMetadata.NamespaceUri); |
| | | 621 | | } |
| | | 622 | | |
| | 238 | 623 | | attribute.Value = actionUri; |
| | 238 | 624 | | wsdlOperationMessage.ExtensibleAttributes = new XmlAttribute[] { attribute }; |
| | 238 | 625 | | } |
| | | 626 | | |
| | | 627 | | internal static void AddAddressToWsdlPort(WsdlNS.Port wsdlPort, EndpointAddress addr, AddressingVersion addr |
| | | 628 | | { |
| | 32 | 629 | | if (addressing == AddressingVersion.None) |
| | | 630 | | { |
| | 21 | 631 | | return; |
| | | 632 | | } |
| | | 633 | | |
| | 11 | 634 | | MemoryStream stream = new MemoryStream(); |
| | 11 | 635 | | XmlWriter xw = XmlWriter.Create(stream); |
| | 11 | 636 | | xw.WriteStartElement("temp"); |
| | | 637 | | |
| | 11 | 638 | | if (addressing == AddressingVersion.WSAddressing10) |
| | | 639 | | { |
| | 11 | 640 | | xw.WriteAttributeString("xmlns", MetadataStrings.Addressing10.Prefix, null, MetadataStrings.Addressi |
| | | 641 | | } |
| | 0 | 642 | | else if (addressing == AddressingVersion.WSAddressingAugust2004) |
| | | 643 | | { |
| | 0 | 644 | | xw.WriteAttributeString("xmlns", MetadataStrings.Addressing200408.Prefix, null, MetadataStrings.Addr |
| | | 645 | | } |
| | | 646 | | else |
| | | 647 | | { |
| | 0 | 648 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( |
| | 0 | 649 | | new InvalidOperationException(SR.Format(SR.AddressingVersionNotSupported, addressing))); |
| | | 650 | | } |
| | | 651 | | |
| | 11 | 652 | | addr.WriteTo(addressing, xw); |
| | 11 | 653 | | xw.WriteEndElement(); |
| | | 654 | | |
| | 11 | 655 | | xw.Flush(); |
| | 11 | 656 | | stream.Seek(0, SeekOrigin.Begin); |
| | | 657 | | |
| | 11 | 658 | | XmlReader xr = XmlReader.Create(stream); |
| | 11 | 659 | | xr.MoveToContent(); |
| | 11 | 660 | | XmlElement endpointRef = (XmlElement)XmlDoc.ReadNode(xr).ChildNodes[0]; |
| | | 661 | | |
| | 11 | 662 | | wsdlPort.Extensions.Add(endpointRef); |
| | 11 | 663 | | } |
| | | 664 | | |
| | | 665 | | internal static void AddWSAddressingAssertion(MetadataExporter exporter, PolicyConversionContext context, Ad |
| | | 666 | | { |
| | | 667 | | XmlElement addressingAssertion; |
| | 41 | 668 | | if (addressVersion == AddressingVersion.WSAddressingAugust2004) |
| | | 669 | | { |
| | 0 | 670 | | addressingAssertion = XmlDoc.CreateElement(MetadataStrings.Addressing200408.Policy.Prefix, |
| | 0 | 671 | | MetadataStrings.Addressing200408.Policy.UsingAddressing, |
| | 0 | 672 | | MetadataStrings.Addressing200408.Policy.NamespaceUri); |
| | | 673 | | } |
| | 41 | 674 | | else if (addressVersion == AddressingVersion.WSAddressing10) |
| | | 675 | | { |
| | 20 | 676 | | if (exporter.PolicyVersion == PolicyVersion.Policy12) |
| | | 677 | | { |
| | 20 | 678 | | addressingAssertion = XmlDoc.CreateElement(MetadataStrings.Addressing10.WsdlBindingPolicy.Prefix |
| | 20 | 679 | | MetadataStrings.Addressing10.WsdlBindingPolicy.UsingAddressing, |
| | 20 | 680 | | MetadataStrings.Addressing10.WsdlBindingPolicy.NamespaceUri); |
| | | 681 | | } |
| | | 682 | | else |
| | | 683 | | { |
| | 0 | 684 | | addressingAssertion = XmlDoc.CreateElement(MetadataStrings.Addressing10.MetadataPolicy.Prefix, |
| | 0 | 685 | | MetadataStrings.Addressing10.MetadataPolicy.Addressing, |
| | 0 | 686 | | MetadataStrings.Addressing10.MetadataPolicy.NamespaceUri); |
| | | 687 | | |
| | | 688 | | // On NetFx, there is an enum SupportedAddressingMode which is only used by CompositeDuplexBindi |
| | | 689 | | // which we don't support yet. This means all transports are treated as though they are using |
| | | 690 | | // SupportedAddressingMode.Anonymous. This code has been modified to only have the behavior of t |
| | | 691 | | |
| | | 692 | | string responsesAssertionLocalName; |
| | 0 | 693 | | responsesAssertionLocalName = MetadataStrings.Addressing10.MetadataPolicy.AnonymousResponses; |
| | | 694 | | |
| | 0 | 695 | | XmlElement innerPolicyElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix, |
| | 0 | 696 | | MetadataStrings.WSPolicy.Elements.Policy, |
| | 0 | 697 | | MetadataStrings.WSPolicy.NamespaceUri15); |
| | | 698 | | |
| | 0 | 699 | | XmlElement responsesAssertion = XmlDoc.CreateElement(MetadataStrings.Addressing10.MetadataPolicy |
| | 0 | 700 | | responsesAssertionLocalName, |
| | 0 | 701 | | MetadataStrings.Addressing10.MetadataPolicy.NamespaceUri); |
| | | 702 | | |
| | 0 | 703 | | innerPolicyElement.AppendChild(responsesAssertion); |
| | 0 | 704 | | addressingAssertion.AppendChild(innerPolicyElement); |
| | | 705 | | } |
| | | 706 | | } |
| | 21 | 707 | | else if (addressVersion == AddressingVersion.None) |
| | | 708 | | { |
| | | 709 | | // do nothing |
| | 21 | 710 | | addressingAssertion = null; |
| | | 711 | | } |
| | | 712 | | else |
| | | 713 | | { |
| | 0 | 714 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( |
| | 0 | 715 | | new InvalidOperationException(SR.Format(SR.AddressingVersionNotSupported, addressVersion))); |
| | | 716 | | } |
| | | 717 | | |
| | 41 | 718 | | if (addressingAssertion != null) |
| | | 719 | | { |
| | 20 | 720 | | context.GetBindingAssertions().Add(addressingAssertion); |
| | | 721 | | } |
| | 41 | 722 | | } |
| | | 723 | | } |
| | | 724 | | |
| | | 725 | | private class WSPolicyAttachmentHelper |
| | | 726 | | { |
| | | 727 | | private readonly PolicyVersion _policyVersion; |
| | | 728 | | |
| | 32 | 729 | | internal WSPolicyAttachmentHelper(PolicyVersion policyVersion) |
| | | 730 | | { |
| | 32 | 731 | | _policyVersion = policyVersion; |
| | 32 | 732 | | } |
| | | 733 | | |
| | | 734 | | internal void AttachPolicy(ServiceEndpoint endpoint, WsdlEndpointConversionContext endpointContext, PolicyCo |
| | | 735 | | { |
| | 32 | 736 | | SortedList<string, string> policyKeys = new SortedList<string, string>(); |
| | 32 | 737 | | NamingHelper.DoesNameExist policyKeyIsUnique |
| | 46 | 738 | | = (string name, object nameCollection) => policyKeys.ContainsKey(name); |
| | | 739 | | |
| | | 740 | | string key, keyBase; |
| | | 741 | | ICollection<XmlElement> assertions; |
| | | 742 | | |
| | 32 | 743 | | WsdlNS.ServiceDescription policyWsdl = endpointContext.WsdlBinding.ServiceDescription; |
| | | 744 | | |
| | 32 | 745 | | assertions = policyContext.GetBindingAssertions(); |
| | | 746 | | |
| | | 747 | | // Add [wsdl:Binding] level Policy |
| | 32 | 748 | | WsdlNS.Binding wsdlBinding = endpointContext.WsdlBinding; |
| | 32 | 749 | | if (assertions.Count > 0) |
| | | 750 | | { |
| | 14 | 751 | | keyBase = CreateBindingPolicyKey(wsdlBinding); |
| | 14 | 752 | | key = NamingHelper.GetUniqueName(keyBase, policyKeyIsUnique, null); |
| | 14 | 753 | | policyKeys.Add(key, key); |
| | 14 | 754 | | AttachItemPolicy(assertions, key, policyWsdl, wsdlBinding); |
| | | 755 | | } |
| | | 756 | | |
| | 382 | 757 | | foreach (OperationDescription operation in endpoint.Contract.Operations) |
| | | 758 | | { |
| | 159 | 759 | | if (!OperationIsExportable(operation)) |
| | | 760 | | { |
| | | 761 | | continue; |
| | | 762 | | } |
| | | 763 | | |
| | 159 | 764 | | assertions = policyContext.GetOperationBindingAssertions(operation); |
| | | 765 | | |
| | | 766 | | // Add [wsdl:Binding/wsdl:operation] policy |
| | 159 | 767 | | if (assertions.Count > 0) |
| | | 768 | | { |
| | 0 | 769 | | WsdlNS.OperationBinding wsdlOperationBinding = endpointContext.GetOperationBinding(operation); |
| | 0 | 770 | | keyBase = CreateOperationBindingPolicyKey(wsdlOperationBinding); |
| | 0 | 771 | | key = NamingHelper.GetUniqueName(keyBase, policyKeyIsUnique, null); |
| | 0 | 772 | | policyKeys.Add(key, key); |
| | 0 | 773 | | AttachItemPolicy(assertions, key, policyWsdl, wsdlOperationBinding); |
| | | 774 | | } |
| | | 775 | | |
| | | 776 | | // |
| | | 777 | | // Add [wsdl:Binding/wsdl:operation] child policy |
| | | 778 | | // |
| | | 779 | | |
| | 954 | 780 | | foreach (MessageDescription message in operation.Messages) |
| | | 781 | | { |
| | 318 | 782 | | assertions = policyContext.GetMessageBindingAssertions(message); |
| | | 783 | | |
| | | 784 | | // Add [wsdl:Binding/wsdl:operation/wsdl:(input, output, message)] policy |
| | 318 | 785 | | if (assertions.Count > 0) |
| | | 786 | | { |
| | 0 | 787 | | WsdlNS.MessageBinding wsdlMessageBinding = endpointContext.GetMessageBinding(message); |
| | 0 | 788 | | keyBase = CreateMessageBindingPolicyKey(wsdlMessageBinding, message.Direction); |
| | 0 | 789 | | key = NamingHelper.GetUniqueName(keyBase, policyKeyIsUnique, null); |
| | 0 | 790 | | policyKeys.Add(key, key); |
| | 0 | 791 | | AttachItemPolicy(assertions, key, policyWsdl, wsdlMessageBinding); |
| | | 792 | | } |
| | | 793 | | } |
| | | 794 | | |
| | 318 | 795 | | foreach (FaultDescription fault in operation.Faults) |
| | | 796 | | { |
| | 0 | 797 | | assertions = policyContext.GetFaultBindingAssertions(fault); |
| | | 798 | | |
| | | 799 | | // Add [wsdl:Binding/wsdl:operation/wsdl:fault] policy |
| | 0 | 800 | | if (assertions.Count > 0) |
| | | 801 | | { |
| | 0 | 802 | | WsdlNS.FaultBinding wsdlFaultBinding = endpointContext.GetFaultBinding(fault); |
| | 0 | 803 | | keyBase = CreateFaultBindingPolicyKey(wsdlFaultBinding); |
| | 0 | 804 | | key = NamingHelper.GetUniqueName(keyBase, policyKeyIsUnique, null); |
| | 0 | 805 | | policyKeys.Add(key, key); |
| | 0 | 806 | | AttachItemPolicy(assertions, key, policyWsdl, wsdlFaultBinding); |
| | | 807 | | } |
| | | 808 | | } |
| | | 809 | | } |
| | 32 | 810 | | } |
| | | 811 | | |
| | | 812 | | private void AttachItemPolicy(ICollection<XmlElement> assertions, string key, WsdlNS.ServiceDescription poli |
| | | 813 | | { |
| | 14 | 814 | | string policyKey = InsertPolicy(key, policyWsdl, assertions); |
| | 14 | 815 | | InsertPolicyReference(policyKey, item); |
| | 14 | 816 | | } |
| | | 817 | | |
| | | 818 | | private void InsertPolicyReference(string policyKey, WsdlNS.DocumentableItem item) |
| | | 819 | | { |
| | | 820 | | //Create wsp:PolicyReference Element On DocumentableItem |
| | | 821 | | //------------------------------------------------------------------------------------------------------ |
| | 14 | 822 | | XmlElement policyReferenceElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix, |
| | 14 | 823 | | MetadataStrings.WSPolicy.Elements.PolicyReference, |
| | 14 | 824 | | _policyVersion.Namespace); |
| | | 825 | | |
| | | 826 | | //Create wsp:PolicyURIs Attribute On DocumentableItem |
| | | 827 | | //------------------------------------------------------------------------------------------------------ |
| | 14 | 828 | | XmlAttribute uriAttribute = XmlDoc.CreateAttribute(MetadataStrings.WSPolicy.Attributes.URI); |
| | | 829 | | |
| | 14 | 830 | | uriAttribute.Value = policyKey; |
| | 14 | 831 | | policyReferenceElement.Attributes.Append(uriAttribute); |
| | 14 | 832 | | item.Extensions.Add(policyReferenceElement); |
| | 14 | 833 | | } |
| | | 834 | | |
| | | 835 | | private string InsertPolicy(string key, WsdlNS.ServiceDescription policyWsdl, ICollection<XmlElement> assert |
| | | 836 | | { |
| | | 837 | | // Create [wsp:Policy] |
| | 14 | 838 | | XmlElement policyElement = CreatePolicyElement(assertions); |
| | | 839 | | |
| | | 840 | | //Create [wsp:Policy/@wsu:Id] |
| | 14 | 841 | | XmlAttribute idAttribute = XmlDoc.CreateAttribute(MetadataStrings.Wsu.Prefix, |
| | 14 | 842 | | MetadataStrings.Wsu.Attributes.Id, |
| | 14 | 843 | | MetadataStrings.Wsu.NamespaceUri); |
| | 14 | 844 | | idAttribute.Value = key; |
| | 14 | 845 | | policyElement.SetAttributeNode(idAttribute); |
| | | 846 | | |
| | | 847 | | // Add wsp:Policy To WSDL |
| | 14 | 848 | | if (policyWsdl != null) |
| | | 849 | | { |
| | 14 | 850 | | policyWsdl.Extensions.Add(policyElement); |
| | | 851 | | } |
| | | 852 | | |
| | 14 | 853 | | return string.Format(CultureInfo.InvariantCulture, "#{0}", key); |
| | | 854 | | } |
| | | 855 | | |
| | | 856 | | private XmlElement CreatePolicyElement(ICollection<XmlElement> assertions) |
| | | 857 | | { |
| | | 858 | | // Create [wsp:Policy] |
| | 14 | 859 | | XmlElement policyElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix, |
| | 14 | 860 | | MetadataStrings.WSPolicy.Elements.Policy, |
| | 14 | 861 | | _policyVersion.Namespace); |
| | | 862 | | |
| | | 863 | | // Create [wsp:Policy/wsp:ExactlyOne] |
| | 14 | 864 | | XmlElement exactlyOneElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix, |
| | 14 | 865 | | MetadataStrings.WSPolicy.Elements.ExactlyOne, |
| | 14 | 866 | | _policyVersion.Namespace); |
| | 14 | 867 | | policyElement.AppendChild(exactlyOneElement); |
| | | 868 | | |
| | | 869 | | // Create [wsp:Policy/wsp:ExactlyOne/wsp:All] |
| | 14 | 870 | | XmlElement allElement = XmlDoc.CreateElement(MetadataStrings.WSPolicy.Prefix, |
| | 14 | 871 | | MetadataStrings.WSPolicy.Elements.All, |
| | 14 | 872 | | _policyVersion.Namespace); |
| | 14 | 873 | | exactlyOneElement.AppendChild(allElement); |
| | | 874 | | |
| | | 875 | | // Add [wsp:Policy/wsp:ExactlyOne/wsp:All/*] |
| | 138 | 876 | | foreach (XmlElement assertion in assertions) |
| | | 877 | | { |
| | 55 | 878 | | XmlNode iNode = XmlDoc.ImportNode(assertion, true); |
| | 55 | 879 | | allElement.AppendChild(iNode); |
| | | 880 | | } |
| | | 881 | | |
| | 14 | 882 | | return policyElement; |
| | | 883 | | } |
| | | 884 | | |
| | 14 | 885 | | private static string CreateBindingPolicyKey(WsdlNS.Binding wsdlBinding) => string.Format(CultureInfo.Invari |
| | | 886 | | |
| | 0 | 887 | | private static string CreateOperationBindingPolicyKey(WsdlNS.OperationBinding wsdlOperationBinding) => strin |
| | 0 | 888 | | wsdlOperationBinding.Binding.Name, |
| | 0 | 889 | | wsdlOperationBinding.Name); |
| | | 890 | | |
| | | 891 | | private static string CreateMessageBindingPolicyKey(WsdlNS.MessageBinding wsdlMessageBinding, MessageDirecti |
| | | 892 | | { |
| | 0 | 893 | | WsdlNS.OperationBinding wsdlOperationBinding = wsdlMessageBinding.OperationBinding; |
| | 0 | 894 | | WsdlNS.Binding wsdlBinding = wsdlOperationBinding.Binding; |
| | | 895 | | |
| | 0 | 896 | | if (direction == MessageDirection.Input) |
| | | 897 | | { |
| | 0 | 898 | | return string.Format(CultureInfo.InvariantCulture, "{0}_{1}_Input_policy", wsdlBinding.Name, wsdlOpe |
| | | 899 | | } |
| | | 900 | | else |
| | | 901 | | { |
| | 0 | 902 | | return string.Format(CultureInfo.InvariantCulture, "{0}_{1}_output_policy", wsdlBinding.Name, wsdlOp |
| | | 903 | | } |
| | | 904 | | } |
| | | 905 | | |
| | | 906 | | private static string CreateFaultBindingPolicyKey(WsdlNS.FaultBinding wsdlFaultBinding) |
| | | 907 | | { |
| | 0 | 908 | | WsdlNS.OperationBinding wsdlOperationBinding = wsdlFaultBinding.OperationBinding; |
| | 0 | 909 | | WsdlNS.Binding wsdlBinding = wsdlOperationBinding.Binding; |
| | 0 | 910 | | if (string.IsNullOrEmpty(wsdlFaultBinding.Name)) |
| | | 911 | | { |
| | 0 | 912 | | return string.Format(CultureInfo.InvariantCulture, "{0}_{1}_Fault", wsdlBinding.Name, wsdlOperationB |
| | | 913 | | } |
| | | 914 | | else |
| | | 915 | | { |
| | 0 | 916 | | return string.Format(CultureInfo.InvariantCulture, "{0}_{1}_{2}_Fault", wsdlBinding.Name, wsdlOperat |
| | | 917 | | } |
| | | 918 | | } |
| | | 919 | | |
| | | 920 | | } |
| | | 921 | | |
| | | 922 | | private class WsdlNamespaceHelper |
| | | 923 | | { |
| | | 924 | | private XmlSerializerNamespaces _xmlSerializerNamespaces; |
| | | 925 | | private readonly PolicyVersion _policyVersion; |
| | | 926 | | internal XmlSerializerNamespaces SerializerNamespaces |
| | | 927 | | { |
| | | 928 | | get |
| | | 929 | | { |
| | 24 | 930 | | if (_xmlSerializerNamespaces == null) |
| | | 931 | | { |
| | 24 | 932 | | XmlSerializerNamespaceWrapper namespaces = new XmlSerializerNamespaceWrapper(); |
| | 24 | 933 | | namespaces.Add("wsdl", WsdlNS.ServiceDescription.Namespace); |
| | 24 | 934 | | namespaces.Add("xsd", XmlSchema.Namespace); |
| | 24 | 935 | | namespaces.Add(MetadataStrings.WSPolicy.Prefix, _policyVersion.Namespace); |
| | 24 | 936 | | namespaces.Add(MetadataStrings.Wsu.Prefix, MetadataStrings.Wsu.NamespaceUri); |
| | 24 | 937 | | namespaces.Add(MetadataStrings.Addressing200408.Prefix, MetadataStrings.Addressing200408.Namespa |
| | 24 | 938 | | namespaces.Add(MetadataStrings.Addressing200408.Policy.Prefix, MetadataStrings.Addressing200408. |
| | 24 | 939 | | namespaces.Add(MetadataStrings.Addressing10.Prefix, MetadataStrings.Addressing10.NamespaceUri); |
| | 24 | 940 | | namespaces.Add(MetadataStrings.Addressing10.WsdlBindingPolicy.Prefix, MetadataStrings.Addressing |
| | 24 | 941 | | namespaces.Add(MetadataStrings.Addressing10.MetadataPolicy.Prefix, MetadataStrings.Addressing10. |
| | 24 | 942 | | namespaces.Add(MetadataStrings.MetadataExchangeStrings.Prefix, MetadataStrings.MetadataExchangeS |
| | 24 | 943 | | namespaces.Add(NetSessionHelper.Prefix, NetSessionHelper.NamespaceUri); |
| | | 944 | | |
| | 24 | 945 | | namespaces.Add("soapenc", "http://schemas.xmlsoap.org/soap/encoding/"); |
| | 24 | 946 | | namespaces.Add("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/"); |
| | 24 | 947 | | namespaces.Add("soap", "http://schemas.xmlsoap.org/wsdl/soap/"); |
| | | 948 | | |
| | 24 | 949 | | _xmlSerializerNamespaces = namespaces.GetNamespaces(); |
| | | 950 | | } |
| | | 951 | | |
| | 24 | 952 | | return _xmlSerializerNamespaces; |
| | | 953 | | } |
| | | 954 | | } |
| | | 955 | | |
| | 24 | 956 | | internal WsdlNamespaceHelper(PolicyVersion policyVersion) |
| | | 957 | | { |
| | 24 | 958 | | _policyVersion = policyVersion; |
| | 24 | 959 | | } |
| | | 960 | | |
| | | 961 | | // doesn't care if you add a duplicate prefix |
| | | 962 | | private class XmlSerializerNamespaceWrapper |
| | | 963 | | { |
| | 24 | 964 | | private readonly XmlSerializerNamespaces _namespaces = new XmlSerializerNamespaces(); |
| | 24 | 965 | | private readonly Dictionary<string, string> _lookup = new Dictionary<string, string>(); |
| | | 966 | | |
| | | 967 | | internal void Add(string prefix, string namespaceUri) |
| | | 968 | | { |
| | 336 | 969 | | if (!_lookup.ContainsKey(prefix)) |
| | | 970 | | { |
| | 336 | 971 | | _namespaces.Add(prefix, namespaceUri); |
| | 336 | 972 | | _lookup.Add(prefix, namespaceUri); |
| | | 973 | | } |
| | 336 | 974 | | } |
| | | 975 | | |
| | 24 | 976 | | internal XmlSerializerNamespaces GetNamespaces() => _namespaces; |
| | | 977 | | } |
| | | 978 | | |
| | | 979 | | internal static string FindOrCreatePrefix(string prefixBase, string ns, params WsdlNS.DocumentableItem[] sco |
| | | 980 | | { |
| | 0 | 981 | | if (!(scopes.Length > 0)) |
| | | 982 | | { |
| | | 983 | | Fx.Assert("You must pass at least one namespaceScope"); |
| | 0 | 984 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Forma |
| | | 985 | | } |
| | | 986 | | |
| | | 987 | | string prefix; |
| | 0 | 988 | | if (string.IsNullOrEmpty(ns)) |
| | | 989 | | { |
| | 0 | 990 | | prefix = string.Empty; |
| | | 991 | | } |
| | | 992 | | else |
| | | 993 | | { |
| | | 994 | | //See if a prefix for the namespace has already been defined at one of the scopes |
| | 0 | 995 | | for (int j = 0; j < scopes.Length; j++) |
| | | 996 | | { |
| | 0 | 997 | | if (TryMatchNamespace(scopes[j].Namespaces.ToArray(), ns, out prefix)) |
| | | 998 | | { |
| | 0 | 999 | | return prefix; |
| | | 1000 | | } |
| | | 1001 | | } |
| | | 1002 | | |
| | | 1003 | | // Create prefix definition at the nearest scope. |
| | 0 | 1004 | | int i = 0; |
| | 0 | 1005 | | prefix = prefixBase + i.ToString(CultureInfo.InvariantCulture); |
| | | 1006 | | |
| | | 1007 | | //hsomu, consider do we need to check at higher scopes as well? |
| | 0 | 1008 | | while (PrefixExists(scopes[0].Namespaces.ToArray(), prefix)) |
| | | 1009 | | { |
| | 0 | 1010 | | prefix = prefixBase + (++i).ToString(CultureInfo.InvariantCulture); |
| | | 1011 | | } |
| | | 1012 | | } |
| | | 1013 | | |
| | 0 | 1014 | | scopes[0].Namespaces.Add(prefix, ns); |
| | 0 | 1015 | | return prefix; |
| | | 1016 | | } |
| | | 1017 | | |
| | 0 | 1018 | | private static bool PrefixExists(XmlQualifiedName[] prefixDefinitions, string prefix) => Array.Exists(prefix |
| | | 1019 | | |
| | | 1020 | | private static bool TryMatchNamespace(XmlQualifiedName[] prefixDefinitions, string ns, out string prefix) |
| | | 1021 | | { |
| | 0 | 1022 | | XmlQualifiedName foundPrefixDef = prefixDefinitions.Where(prefixDef => prefixDef.Namespace == ns).FirstO |
| | 0 | 1023 | | prefix = foundPrefixDef?.Name; |
| | 0 | 1024 | | return foundPrefixDef != null; |
| | | 1025 | | } |
| | | 1026 | | } |
| | | 1027 | | |
| | | 1028 | | internal static class WsdlNamingHelper |
| | | 1029 | | { |
| | 24 | 1030 | | internal static XmlQualifiedName GetPortTypeQName(ContractDescription contract) => new XmlQualifiedName(cont |
| | | 1031 | | |
| | | 1032 | | internal static string GetUniqueName(string baseName, Func<string, object, bool> doesNameExist, object nameC |
| | | 1033 | | { |
| | 0 | 1034 | | for (int i = 0; i < int.MaxValue; i++) |
| | | 1035 | | { |
| | 0 | 1036 | | string name = i > 0 ? baseName + i : baseName; |
| | 0 | 1037 | | if (!doesNameExist(name, nameCollection)) |
| | | 1038 | | { |
| | 0 | 1039 | | return name; |
| | | 1040 | | } |
| | | 1041 | | } |
| | | 1042 | | |
| | | 1043 | | Fx.Assert("Too Many Names"); |
| | 0 | 1044 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(Cu |
| | | 1045 | | } |
| | | 1046 | | |
| | | 1047 | | internal static XmlQualifiedName GetBindingQName(ServiceEndpoint endpoint, WsdlExporter exporter, out bool w |
| | | 1048 | | { |
| | | 1049 | | // due to problems in Sysytem.Web.Services.Descriprion.ServiceDescription.Write() (double encoding) meth |
| | | 1050 | | // wsdl:binding item: we need to make sure that XmlConvert.EncodeLocalName will not find any problems wi |
| | | 1051 | | // consider changing the name here to something that will not be encoded by XmlSerializer (GenerateSimpl |
| | 32 | 1052 | | string localName = endpoint.Name; |
| | 32 | 1053 | | string bindingWsdlNamespace = endpoint.Binding.Namespace; |
| | 32 | 1054 | | string uniquifiedLocalName = NamingHelper.GetUniqueName(localName, WsdlBindingQNameExists(exporter, bind |
| | 32 | 1055 | | wasUniquified = localName != uniquifiedLocalName; |
| | 32 | 1056 | | return new XmlQualifiedName(uniquifiedLocalName, bindingWsdlNamespace); |
| | | 1057 | | } |
| | | 1058 | | |
| | | 1059 | | private static NamingHelper.DoesNameExist WsdlBindingQNameExists(WsdlExporter exporter, string bindingWsdlNa |
| | | 1060 | | { |
| | | 1061 | | bool WsdlBindingQNameExistsImpl(string localName, object nameCollection) |
| | | 1062 | | { |
| | 51 | 1063 | | WsdlNS.ServiceDescription wsdl = exporter.GeneratedWsdlDocuments[bindingWsdlNamespace]; |
| | 51 | 1064 | | if (wsdl != null && wsdl.Bindings[localName] != null) |
| | | 1065 | | { |
| | 19 | 1066 | | return true; |
| | | 1067 | | } |
| | | 1068 | | |
| | 32 | 1069 | | return false; |
| | | 1070 | | } |
| | | 1071 | | |
| | 32 | 1072 | | return WsdlBindingQNameExistsImpl; |
| | | 1073 | | } |
| | | 1074 | | |
| | 32 | 1075 | | internal static string GetPortName(ServiceEndpoint endpoint, WsdlNS.Service wsdlService) => NamingHelper.Get |
| | | 1076 | | |
| | | 1077 | | private static NamingHelper.DoesNameExist ServiceContainsPort(WsdlNS.Service service) |
| | | 1078 | | { |
| | 142 | 1079 | | return (string portName, object nameCollection) => service.Ports.Cast<WsdlNS.Port>().Any(port => port.Na |
| | | 1080 | | } |
| | | 1081 | | |
| | 278 | 1082 | | internal static string GetWsdlOperationName(OperationDescription operationDescription) => operationDescripti |
| | | 1083 | | } |
| | | 1084 | | |
| | | 1085 | | internal static class NetSessionHelper |
| | | 1086 | | { |
| | | 1087 | | internal const string NamespaceUri = "http://schemas.microsoft.com/ws/2005/12/wsdl/contract"; |
| | | 1088 | | internal const string Prefix = "msc"; |
| | | 1089 | | internal const string UsingSession = "usingSession"; |
| | | 1090 | | internal const string IsInitiating = "isInitiating"; |
| | | 1091 | | internal const string IsTerminating = "isTerminating"; |
| | | 1092 | | internal const string True = "true"; |
| | | 1093 | | internal const string False = "false"; |
| | | 1094 | | |
| | | 1095 | | internal static void AddUsingSessionAttributeIfNeeded(WsdlNS.PortType wsdlPortType, ContractDescription cont |
| | | 1096 | | { |
| | | 1097 | | bool sessionValue; |
| | | 1098 | | |
| | 24 | 1099 | | if (contract.SessionMode == SessionMode.Required) |
| | | 1100 | | { |
| | 0 | 1101 | | sessionValue = true; |
| | | 1102 | | } |
| | 24 | 1103 | | else if (contract.SessionMode == SessionMode.NotAllowed) |
| | | 1104 | | { |
| | 0 | 1105 | | sessionValue = false; |
| | | 1106 | | } |
| | | 1107 | | else |
| | | 1108 | | { |
| | 24 | 1109 | | return; |
| | | 1110 | | } |
| | | 1111 | | |
| | 0 | 1112 | | wsdlPortType.ExtensibleAttributes = CloneAndAddToAttributes(wsdlPortType.ExtensibleAttributes, Prefix, |
| | 0 | 1113 | | UsingSession, NamespaceUri, ToValue(sessionValue)); |
| | 0 | 1114 | | } |
| | | 1115 | | |
| | | 1116 | | internal static void AddInitiatingTerminatingAttributesIfNeeded(WsdlNS.Operation wsdlOperation, |
| | | 1117 | | OperationDescription operation, ContractDescription contract) |
| | | 1118 | | { |
| | 119 | 1119 | | if (contract.SessionMode == SessionMode.Required) |
| | | 1120 | | { |
| | 0 | 1121 | | AddInitiatingAttribute(wsdlOperation, operation.IsInitiating); |
| | 0 | 1122 | | AddTerminatingAttribute(wsdlOperation, operation.IsTerminating); |
| | | 1123 | | } |
| | 119 | 1124 | | } |
| | | 1125 | | |
| | 0 | 1126 | | private static void AddInitiatingAttribute(System.Web.Services.Description.Operation wsdlOperation, bool isI |
| | 0 | 1127 | | IsInitiating, NamespaceUri, ToValue(isInitiating)); |
| | | 1128 | | |
| | 0 | 1129 | | private static void AddTerminatingAttribute(System.Web.Services.Description.Operation wsdlOperation, bool is |
| | 0 | 1130 | | IsTerminating, NamespaceUri, ToValue(isTerminating)); |
| | | 1131 | | |
| | | 1132 | | private static XmlAttribute[] CloneAndAddToAttributes(XmlAttribute[] originalAttributes, string prefix, stri |
| | | 1133 | | { |
| | 0 | 1134 | | XmlAttribute newAttribute = XmlDoc.CreateAttribute(prefix, localName, ns); |
| | 0 | 1135 | | newAttribute.Value = value; |
| | | 1136 | | |
| | 0 | 1137 | | int originalAttributeCount = 0; |
| | 0 | 1138 | | if (originalAttributes != null) |
| | | 1139 | | { |
| | 0 | 1140 | | originalAttributeCount = originalAttributes.Length; |
| | | 1141 | | } |
| | | 1142 | | |
| | 0 | 1143 | | XmlAttribute[] attributes = new XmlAttribute[originalAttributeCount + 1]; |
| | | 1144 | | |
| | 0 | 1145 | | if (originalAttributes != null) |
| | | 1146 | | { |
| | 0 | 1147 | | originalAttributes.CopyTo(attributes, 0); |
| | | 1148 | | } |
| | | 1149 | | |
| | 0 | 1150 | | attributes[attributes.Length - 1] = newAttribute; |
| | | 1151 | | |
| | 0 | 1152 | | return attributes; |
| | | 1153 | | } |
| | | 1154 | | |
| | 0 | 1155 | | private static string ToValue(bool b) => b ? True : False; |
| | | 1156 | | } |
| | | 1157 | | |
| | | 1158 | | private void CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension) |
| | | 1159 | | { |
| | | 1160 | | try |
| | | 1161 | | { |
| | 119 | 1162 | | extension.ExportContract(this, contractContext); |
| | 119 | 1163 | | } |
| | 0 | 1164 | | catch (Exception e) |
| | | 1165 | | { |
| | 0 | 1166 | | if (Fx.IsFatal(e)) |
| | | 1167 | | { |
| | 0 | 1168 | | throw; |
| | | 1169 | | } |
| | | 1170 | | |
| | 0 | 1171 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ThrowExtensionException(contractContext.Contra |
| | | 1172 | | } |
| | 119 | 1173 | | } |
| | | 1174 | | |
| | | 1175 | | private void CallExtension(WsdlEndpointConversionContext endpointContext, IWsdlExportExtension extension) |
| | | 1176 | | { |
| | | 1177 | | try |
| | | 1178 | | { |
| | 223 | 1179 | | extension.ExportEndpoint(this, endpointContext); |
| | 223 | 1180 | | } |
| | 0 | 1181 | | catch (Exception e) |
| | | 1182 | | { |
| | 0 | 1183 | | if (Fx.IsFatal(e)) |
| | | 1184 | | { |
| | 0 | 1185 | | throw; |
| | | 1186 | | } |
| | | 1187 | | |
| | 0 | 1188 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ThrowExtensionException(endpointContext.Endpoi |
| | | 1189 | | } |
| | 223 | 1190 | | } |
| | | 1191 | | |
| | | 1192 | | private Exception ThrowExtensionException(ContractDescription contract, IWsdlExportExtension exporter, Exception |
| | | 1193 | | { |
| | 0 | 1194 | | string contractIdentifier = new XmlQualifiedName(contract.Name, contract.Namespace).ToString(); |
| | 0 | 1195 | | string errorMessage = SR.Format(SR.WsdlExtensionContractExportError, exporter.GetType(), contractIdentifier) |
| | | 1196 | | |
| | 0 | 1197 | | return new InvalidOperationException(errorMessage, e); |
| | | 1198 | | } |
| | | 1199 | | |
| | | 1200 | | private Exception ThrowExtensionException(ServiceEndpoint endpoint, IWsdlExportExtension exporter, Exception e) |
| | | 1201 | | { |
| | | 1202 | | string endpointIdentifier; |
| | 0 | 1203 | | if (endpoint.Address != null && endpoint.Address.Uri != null) |
| | | 1204 | | { |
| | 0 | 1205 | | endpointIdentifier = endpoint.Address.Uri.ToString(); |
| | | 1206 | | } |
| | | 1207 | | else |
| | | 1208 | | { |
| | 0 | 1209 | | endpointIdentifier = string.Format(CultureInfo.InvariantCulture, |
| | 0 | 1210 | | "Contract={1}:{0} ,Binding={3}:{2}", |
| | 0 | 1211 | | endpoint.Contract.Name, |
| | 0 | 1212 | | endpoint.Contract.Namespace, |
| | 0 | 1213 | | endpoint.Binding.Name, |
| | 0 | 1214 | | endpoint.Binding.Namespace); |
| | | 1215 | | } |
| | | 1216 | | |
| | 0 | 1217 | | string errorMessage = SR.Format(SR.WsdlExtensionEndpointExportError, exporter.GetType(), endpointIdentifier) |
| | | 1218 | | |
| | 0 | 1219 | | return new InvalidOperationException(errorMessage, e); |
| | | 1220 | | } |
| | | 1221 | | |
| | | 1222 | | private sealed class BindingDictionaryKey |
| | | 1223 | | { |
| | | 1224 | | public readonly ContractDescription Contract; |
| | | 1225 | | public readonly Binding Binding; |
| | | 1226 | | |
| | 64 | 1227 | | public BindingDictionaryKey(ContractDescription contract, Binding binding) |
| | | 1228 | | { |
| | 64 | 1229 | | Contract = contract; |
| | 64 | 1230 | | Binding = binding; |
| | 64 | 1231 | | } |
| | | 1232 | | |
| | | 1233 | | public override bool Equals(object obj) |
| | | 1234 | | { |
| | 0 | 1235 | | if (obj is BindingDictionaryKey key && key.Binding == Binding && key.Contract == Contract) |
| | | 1236 | | { |
| | 0 | 1237 | | return true; |
| | | 1238 | | } |
| | | 1239 | | |
| | 0 | 1240 | | return false; |
| | | 1241 | | } |
| | | 1242 | | |
| | 40 | 1243 | | public override int GetHashCode() => Contract.GetHashCode() ^ Binding.GetHashCode(); |
| | | 1244 | | } |
| | | 1245 | | |
| | | 1246 | | private sealed class EndpointDictionaryKey |
| | | 1247 | | { |
| | | 1248 | | public readonly ServiceEndpoint Endpoint; |
| | | 1249 | | public readonly XmlQualifiedName ServiceQName; |
| | | 1250 | | |
| | 32 | 1251 | | public EndpointDictionaryKey(ServiceEndpoint endpoint, XmlQualifiedName serviceQName) |
| | | 1252 | | { |
| | 32 | 1253 | | Endpoint = endpoint; |
| | 32 | 1254 | | ServiceQName = serviceQName; |
| | 32 | 1255 | | } |
| | | 1256 | | |
| | | 1257 | | public override bool Equals(object obj) |
| | | 1258 | | { |
| | 0 | 1259 | | if (obj is EndpointDictionaryKey key && key.Endpoint == Endpoint && key.ServiceQName == ServiceQName) |
| | | 1260 | | { |
| | 0 | 1261 | | return true; |
| | | 1262 | | } |
| | | 1263 | | |
| | 0 | 1264 | | return false; |
| | | 1265 | | } |
| | | 1266 | | |
| | 40 | 1267 | | public override int GetHashCode() => Endpoint.GetHashCode() ^ ServiceQName.GetHashCode(); |
| | | 1268 | | } |
| | | 1269 | | } |
| | | 1270 | | } |