Skip to content

Commit

Permalink
Merge pull request #1044 from Yozer/feat-custom-wsdl-param-names
Browse files Browse the repository at this point in the history
feat(wsdl-meta): allow to customize message names for operation
  • Loading branch information
andersjonsson committed Jun 1, 2024
2 parents 0c709cd + a0b66f0 commit 789828c
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 17 deletions.
40 changes: 40 additions & 0 deletions src/SoapCore.Tests/Wsdl/DefaultWsdlOperationNameGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.ServiceModel;
using SoapCore.Meta;
using SoapCore.ServiceModel;
using SoapCore.Tests.Wsdl.Services;
using Xunit;

namespace SoapCore.Tests.Wsdl
{
public class DefaultWsdlOperationNameGeneratorTests
{
private readonly ServiceDescription _serviceDescription;
private readonly ServiceModel.OperationDescription _operation;
private readonly DefaultWsdlOperationNameGenerator _generator;

public DefaultWsdlOperationNameGeneratorTests()
{
_serviceDescription = new ServiceDescription(typeof(IEnumService), false);
var contractDescription = new ContractDescription(_serviceDescription, typeof(IEnumService), new ServiceContractAttribute(), false);
var method = typeof(IEnumService).GetMethod(nameof(IEnumService.Method));
var contractAttribute = new OperationContractAttribute();
_operation = new ServiceModel.OperationDescription(contractDescription, method, contractAttribute, false);

_generator = new DefaultWsdlOperationNameGenerator();
}

[Fact]
public void TestGenerateWsdlInputMessageName()
{
var result = _generator.GenerateWsdlInputMessageName(_operation, _serviceDescription);
Assert.Equal("IEnumService_Method_InputMessage", result);
}

[Fact]
public void TestGenerateWsdlOutputMessageName()
{
var result = _generator.GenerateWsdlOutputMessageName(_operation, _serviceDescription);
Assert.Equal("IEnumService_Method_OutputMessage", result);
}
}
}
4 changes: 2 additions & 2 deletions src/SoapCore.Tests/Wsdl/WsdlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1242,8 +1242,8 @@ private async Task<string> GetWsdlFromMetaBodyWriter<T>(SoapSerializer serialize
var xmlNamespaceManager = Namespaces.CreateDefaultXmlNamespaceManager(useMicrosoftGuid);
var defaultBindingName = !string.IsNullOrWhiteSpace(bindingName) ? bindingName : "BasicHttpBinding";
var bodyWriter = serializer == SoapSerializer.DataContractSerializer
? new MetaWCFBodyWriter(service, baseUrl, defaultBindingName, false, new[] { new SoapBindingInfo(MessageVersion.None, bindingName, portName) }) as BodyWriter
: new MetaBodyWriter(service, baseUrl, xmlNamespaceManager, defaultBindingName, new[] { new SoapBindingInfo(MessageVersion.None, bindingName, portName) }, useMicrosoftGuid) as BodyWriter;
? new MetaWCFBodyWriter(service, baseUrl, defaultBindingName, false, new[] { new SoapBindingInfo(MessageVersion.None, bindingName, portName) }, new DefaultWsdlOperationNameGenerator()) as BodyWriter
: new MetaBodyWriter(service, baseUrl, xmlNamespaceManager, defaultBindingName, new[] { new SoapBindingInfo(MessageVersion.None, bindingName, portName) }, useMicrosoftGuid, new DefaultWsdlOperationNameGenerator()) as BodyWriter;
var encoder = new SoapMessageEncoder(MessageVersion.Soap12WSAddressingAugust2004, Encoding.UTF8, false, XmlDictionaryReaderQuotas.Max, false, false, null, bindingName, portName, true);
var responseMessage = Message.CreateMessage(encoder.MessageVersion, null, bodyWriter);
responseMessage = new MetaMessage(
Expand Down
23 changes: 23 additions & 0 deletions src/SoapCore/Meta/IWsdlOperationNameGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using SoapCore.ServiceModel;

namespace SoapCore.Meta
{
public interface IWsdlOperationNameGenerator
{
string GenerateWsdlInputMessageName(OperationDescription operation, ServiceDescription service);
string GenerateWsdlOutputMessageName(OperationDescription operation, ServiceDescription service);
}

public class DefaultWsdlOperationNameGenerator : IWsdlOperationNameGenerator
{
public string GenerateWsdlInputMessageName(OperationDescription operation, ServiceDescription service)
{
return $"{service.GeneralContract.Name}_{operation.Name}_InputMessage";
}

public string GenerateWsdlOutputMessageName(OperationDescription operation, ServiceDescription service)
{
return $"{service.GeneralContract.Name}_{operation.Name}_OutputMessage";
}
}
}
18 changes: 11 additions & 7 deletions src/SoapCore/Meta/MetaBodyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ public class MetaBodyWriter : BodyWriter
private readonly HashSet<string> _builtComplexTypes;
private readonly Dictionary<string, Dictionary<string, string>> _requestedDynamicTypes;

private bool _buildMicrosoftGuid = false;
private readonly bool _buildMicrosoftGuid = false;
private IWsdlOperationNameGenerator _wsdlOperationNameGenerator;


[Obsolete]
public MetaBodyWriter(ServiceDescription service, string baseUrl, Binding binding, XmlNamespaceManager xmlNamespaceManager = null)
Expand All @@ -43,12 +45,13 @@ public MetaBodyWriter(ServiceDescription service, string baseUrl, Binding bindin
xmlNamespaceManager ?? new XmlNamespaceManager(new NameTable()),
binding?.Name ?? "BasicHttpBinding_" + service.GeneralContract.Name,
new[] { new SoapBindingInfo(binding.MessageVersion ?? MessageVersion.None, null, null) },
false)
false,
new DefaultWsdlOperationNameGenerator())

{
}

public MetaBodyWriter(ServiceDescription service, string baseUrl, XmlNamespaceManager xmlNamespaceManager, string bindingName, SoapBindingInfo[] soapBindings, bool buildMicrosoftGuid) : base(isBuffered: true)
public MetaBodyWriter(ServiceDescription service, string baseUrl, XmlNamespaceManager xmlNamespaceManager, string bindingName, SoapBindingInfo[] soapBindings, bool buildMicrosoftGuid, IWsdlOperationNameGenerator wsdlOperationNameGenerator) : base(isBuffered: true)
{
_service = service;
_baseUrl = baseUrl;
Expand All @@ -64,6 +67,7 @@ public MetaBodyWriter(ServiceDescription service, string baseUrl, XmlNamespaceMa
PortName = bindingName;
SoapBindings = soapBindings;
_buildMicrosoftGuid = buildMicrosoftGuid;
_wsdlOperationNameGenerator = wsdlOperationNameGenerator;
}

private SoapBindingInfo[] SoapBindings { get; }
Expand Down Expand Up @@ -546,7 +550,7 @@ private void AddMessage(XmlDictionaryWriter writer)
}

writer.WriteStartElement("wsdl", "message", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", $"{BindingType}_{operation.Name}_InputMessage");
writer.WriteAttributeString("name", _wsdlOperationNameGenerator.GenerateWsdlInputMessageName(operation, _service));

if ((operation.IsMessageContractRequest && hasRequestBody) || !operation.IsMessageContractRequest)
{
Expand Down Expand Up @@ -587,7 +591,7 @@ private void AddMessage(XmlDictionaryWriter writer)
if (!operation.IsOneWay)
{
writer.WriteStartElement("wsdl", "message", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", $"{BindingType}_{operation.Name}_OutputMessage");
writer.WriteAttributeString("name", _wsdlOperationNameGenerator.GenerateWsdlOutputMessageName(operation, _service));
writer.WriteStartElement("wsdl", "part", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", "parameters");
writer.WriteAttributeString("element", "tns:" + responseTypeName);
Expand Down Expand Up @@ -622,12 +626,12 @@ private void AddPortType(XmlDictionaryWriter writer)
writer.WriteStartElement("wsdl", "operation", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", operation.Name);
writer.WriteStartElement("wsdl", "input", Namespaces.WSDL_NS);
writer.WriteAttributeString("message", $"tns:{BindingType}_{operation.Name}_InputMessage");
writer.WriteAttributeString("message", $"tns:{_wsdlOperationNameGenerator.GenerateWsdlInputMessageName(operation, _service)}");
writer.WriteEndElement(); // wsdl:input
if (!operation.IsOneWay)
{
writer.WriteStartElement("wsdl", "output", Namespaces.WSDL_NS);
writer.WriteAttributeString("message", $"tns:{BindingType}_{operation.Name}_OutputMessage");
writer.WriteAttributeString("message", $"tns:{_wsdlOperationNameGenerator.GenerateWsdlOutputMessageName(operation, _service)}");
writer.WriteEndElement(); // wsdl:output
}

Expand Down
20 changes: 14 additions & 6 deletions src/SoapCore/Meta/MetaWCFBodyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class MetaWCFBodyWriter : BodyWriter
private bool _buildDateTimeOffset;
private bool _buildDataTable;
private string _schemaNamespace;
private IWsdlOperationNameGenerator _wsdlOperationNameGenerator;

[Obsolete]
public MetaWCFBodyWriter(ServiceDescription service, string baseUrl, Binding binding)
Expand All @@ -73,14 +74,21 @@ public MetaWCFBodyWriter(ServiceDescription service, string baseUrl, Binding bin
baseUrl,
binding?.Name ?? "BasicHttpBinding_" + service.GeneralContract.Name,
binding.HasBasicAuth(),
new[] { new SoapBindingInfo(binding.MessageVersion ?? MessageVersion.None, null, null) })
new[] { new SoapBindingInfo(binding.MessageVersion ?? MessageVersion.None, null, null) },
new DefaultWsdlOperationNameGenerator())
{
}

public MetaWCFBodyWriter(ServiceDescription service, string baseUrl, string bindingName, bool hasBasicAuthentication, SoapBindingInfo[] soapBindings) : base(isBuffered: true)
public MetaWCFBodyWriter(ServiceDescription service,
string baseUrl,
string bindingName,
bool hasBasicAuthentication,
SoapBindingInfo[] soapBindings,
IWsdlOperationNameGenerator wsdlOperationNameGenerator) : base(isBuffered: true)
{
_service = service;
_baseUrl = baseUrl;
_wsdlOperationNameGenerator = wsdlOperationNameGenerator;

_arrayToBuild = new Queue<Type>();
_builtEnumTypes = new HashSet<string>();
Expand Down Expand Up @@ -993,7 +1001,7 @@ private void AddMessages(XmlDictionaryWriter writer)
{
// input
writer.WriteStartElement("wsdl", "message", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", $"{BindingType}_{operation.Name}_InputMessage");
writer.WriteAttributeString("name", _wsdlOperationNameGenerator.GenerateWsdlInputMessageName(operation, _service));
writer.WriteStartElement("wsdl", "part", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", "parameters");

Expand All @@ -1014,7 +1022,7 @@ private void AddMessages(XmlDictionaryWriter writer)
if (!operation.IsOneWay)
{
writer.WriteStartElement("wsdl", "message", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", $"{BindingType}_{operation.Name}_OutputMessage");
writer.WriteAttributeString("name", _wsdlOperationNameGenerator.GenerateWsdlOutputMessageName(operation, _service));
writer.WriteStartElement("wsdl", "part", Namespaces.WSDL_NS);
writer.WriteAttributeString("name", "parameters");

Expand Down Expand Up @@ -1062,14 +1070,14 @@ private void AddPortType(XmlDictionaryWriter writer)
writer.WriteAttributeString("name", operation.Name);
writer.WriteStartElement("wsdl", "input", Namespaces.WSDL_NS);
writer.WriteAttributeString("wsam", "Action", Namespaces.WSAM_NS, operation.SoapAction);
writer.WriteAttributeString("message", $"tns:{BindingType}_{operation.Name}_InputMessage");
writer.WriteAttributeString("message", $"tns:{_wsdlOperationNameGenerator.GenerateWsdlInputMessageName(operation, _service)}");
writer.WriteEndElement(); // wsdl:input

if (!operation.IsOneWay)
{
writer.WriteStartElement("wsdl", "output", Namespaces.WSDL_NS);
writer.WriteAttributeString("wsam", "Action", Namespaces.WSAM_NS, operation.SoapAction + "Response");
writer.WriteAttributeString("message", $"tns:{BindingType}_{operation.Name}_OutputMessage");
writer.WriteAttributeString("message", $"tns:{_wsdlOperationNameGenerator.GenerateWsdlOutputMessageName(operation, _service)}");
writer.WriteEndElement(); // wsdl:output
}

Expand Down
4 changes: 2 additions & 2 deletions src/SoapCore/SoapEndpointMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ private async Task ProcessMeta(HttpContext httpContext, bool showDocumentation)
var xmlNamespaceManager = GetXmlNamespaceManager(null);
var bindingName = !string.IsNullOrWhiteSpace(_options.EncoderOptions[0].BindingName) ? _options.EncoderOptions[0].BindingName : "BasicHttpBinding_" + _service.GeneralContract.Name;
var bodyWriter = _options.SoapSerializer == SoapSerializer.XmlSerializer
? new MetaBodyWriter(_service, baseUrl, xmlNamespaceManager, bindingName, _messageEncoders.Select(me => new SoapBindingInfo(me.MessageVersion, me.BindingName, me.PortName)).ToArray(), _options.UseMicrosoftGuid)
: (BodyWriter)new MetaWCFBodyWriter(_service, baseUrl, bindingName, _options.UseBasicAuthentication, _messageEncoders.Select(me => new SoapBindingInfo(me.MessageVersion, me.BindingName, me.PortName)).ToArray());
? new MetaBodyWriter(_service, baseUrl, xmlNamespaceManager, bindingName, _messageEncoders.Select(me => new SoapBindingInfo(me.MessageVersion, me.BindingName, me.PortName)).ToArray(), _options.UseMicrosoftGuid, _options.WsdlOperationNameGenerator)
: (BodyWriter)new MetaWCFBodyWriter(_service, baseUrl, bindingName, _options.UseBasicAuthentication, _messageEncoders.Select(me => new SoapBindingInfo(me.MessageVersion, me.BindingName, me.PortName)).ToArray(), _options.WsdlOperationNameGenerator);

//assumption that you want soap12 if your service supports that
var messageEncoder = _messageEncoders.FirstOrDefault(me => me.MessageVersion == MessageVersion.Soap12WSAddressing10 || me.MessageVersion == MessageVersion.Soap12WSAddressingAugust2004) ?? _messageEncoders[0];
Expand Down
2 changes: 2 additions & 0 deletions src/SoapCore/SoapOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.Xml;
using SoapCore.ServiceModel;

namespace SoapCore
{
Expand Down Expand Up @@ -73,6 +74,7 @@ public class SoapOptions
public bool GenerateSoapActionWithoutContractName { get; set; } = false;

public bool NormalizeNewLines { get; set; } = true;
public IWsdlOperationNameGenerator WsdlOperationNameGenerator { get; set; } = new DefaultWsdlOperationNameGenerator();

[Obsolete]
public static SoapOptions FromSoapCoreOptions<T>(SoapCoreOptions opt)
Expand Down

0 comments on commit 789828c

Please sign in to comment.