Skip to content

Commit

Permalink
Merge pull request #881 from DigDes/develop
Browse files Browse the repository at this point in the history
v1.1.0.30
  • Loading branch information
kotovaleksandr authored Jun 3, 2022
2 parents 9fae093 + 39342ca commit 5e7979e
Show file tree
Hide file tree
Showing 31 changed files with 1,372 additions and 292 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
app.UseRouting();

app.UseEndpoints(endpoints => {
endpoints.UseSoapEndpoint<ServiceContractImpl>("/ServicePath.asmx", new SoapEncoderOptions());
endpoints.UseSoapEndpoint<ServiceContractImpl>("/ServicePath.asmx", new SoapEncoderOptions(), SoapSerializer.DataContractSerializer);
});

}
Expand Down
6 changes: 3 additions & 3 deletions src/SoapCore.Tests/MessageFilter/WsMessageFilterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public async Task NonceCantBePresentWithoutCreated()
var usernameToken = new XElement(
_wsse + "UsernameToken",
new XElement(_wsse + "Username", "yourusername"),
new XElement(_wsse + "Password", "yourpassword"),
new XElement(_wsse + "Password", new XAttribute("Type", _passwordDigest), "yourpassword"),
new XElement(_wsse + "Nonce", ToBase64String(Guid.NewGuid().ToByteArray())));

var filter = new WsMessageFilter("yourusername", "yourpassword");
Expand All @@ -94,7 +94,7 @@ public async Task CreatedCantBePresentWithoutNonce()
var usernameToken = new XElement(
_wsse + "UsernameToken",
new XElement(_wsse + "Username", "yourusername"),
new XElement(_wsse + "Password", "yourpassword"),
new XElement(_wsse + "Password", new XAttribute("Type", _passwordDigest), "yourpassword"),
new XElement(_wsu + "Created", "2003-07-16T01:24:32Z"));

var filter = new WsMessageFilter("yourusername", "yourpassword");
Expand Down Expand Up @@ -138,7 +138,7 @@ public async Task InvalidNonceIsNotAuthorizedEvenInCleartext()
var usernameToken = new XElement(
_wsse + "UsernameToken",
new XElement(_wsse + "Username", "yourusername"),
new XElement(_wsse + "Password", "yourpassword"),
new XElement(_wsse + "Password", new XAttribute("Type", _passwordDigest), "yourpassword"),
new XElement(_wsse + "Nonce", notBase64Encoded),
new XElement(_wsu + "Created", "2020-03-06T19:58:28.134Z"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ public class MessageContractRequestWithArrays
[XmlArrayItem("ComplexModel1")]
public ComplexModel1[] ArrayWithContainers { get; set; }

[MessageBodyMember(Namespace = "http://xmlelement-namespace/", Order = 5)]
[XmlElement("ArrayWithChoiceWithoutContainers11", typeof(ComplexModel1))]
[XmlElement("ArrayWithChoiceWithoutContainers12", typeof(ComplexModel2))]
public object[] ArrayWithChoiceWithoutContainers1 { get; set; }

[MessageBodyMember(Namespace = "http://xmlelement-namespace/", Order = 5)]
[XmlElement("ArrayWithChoiceWithoutContainers21", typeof(ComplexModel1))]
[XmlElement("ArrayWithChoiceWithoutContainers22", typeof(ComplexModel2))]
public object[] ArrayWithChoiceWithoutContainers2 { get; set; }

[MessageBodyMember(Namespace = "http://xmlelement-namespace/", Order = 2)]
[XmlElement("ObjectArrayWithoutContainers")]
public ComplexObject[] ObjectArrayWithoutContainers { get; set; }
Expand All @@ -27,6 +37,11 @@ public class MessageContractRequestWithArrays
[XmlArrayItem("ComplexObject")]
public ComplexObject[] ObjectArrayWithContainers { get; set; }

[MessageBodyMember(Namespace = "http://xmlelement-namespace/", Order = 5)]
[XmlElement("EmptyArrayWithChoiceWithoutContainers1", typeof(ComplexModel1))]
[XmlElement("EmptyArrayWithChoiceWithoutContainers2", typeof(ComplexModel2))]
public object[] EmptyArrayWithChoiceWithoutContainers { get; set; }

[MessageBodyMember(Namespace = "http://xmlelement-namespace/", Order = 4)]
[XmlElement("EmptyArrayWithoutContainers")]
public ComplexModel1[] EmptyArrayWithoutContainers { get; set; }
Expand All @@ -52,6 +67,18 @@ public static MessageContractRequestWithArrays CreateSample()
ComplexModel1.CreateSample2(),
ComplexModel1.CreateSample3()
},
ArrayWithChoiceWithoutContainers1 = new[]
{
ComplexModel1.CreateSample1(),
ComplexModel1.CreateSample2(),
ComplexModel1.CreateSample3()
},
ArrayWithChoiceWithoutContainers2 = new[]
{
ComplexModel2.CreateSample1(),
ComplexModel2.CreateSample2(),
ComplexModel2.CreateSample3()
},
ObjectArrayWithoutContainers = new[]
{
ComplexObject.CreateSample1(),
Expand All @@ -64,6 +91,7 @@ public static MessageContractRequestWithArrays CreateSample()
ComplexObject.CreateSample2(),
ComplexObject.CreateSample3(),
},
EmptyArrayWithChoiceWithoutContainers = new object[0],
EmptyArrayWithoutContainers = new ComplexModel1[0],
EmptyArrayWithContainers = new ComplexModel1[0]
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.ServiceModel;
using System.Text;
Expand Down Expand Up @@ -37,6 +38,31 @@ public async Task ReplaceResponseWithCustomEmptyMessageAsync()
}
}

[TestMethod]
public async Task ReplaceResponseWithPongMessageAsync()
{
var pingValue = "abc";
var body = $@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"">
<soapenv:Body>
<Ping xmlns=""http://tempuri.org/"">
<s>{pingValue}</s>
</Ping>
</soapenv:Body>
</soapenv:Envelope>
";
using (var host = CreateTestHost())
using (var client = host.CreateClient())
using (var content = new StringContent(body, Encoding.UTF8, "text/xml"))
using (var res = host.CreateRequest("/ServiceWithPongProcessor.svc").AddHeader("SOAPAction", @"""Ping""").And(msg => msg.Content = content).PostAsync().Result)
{
res.EnsureSuccessStatusCode();

var response = await res.Content.ReadAsStringAsync();
Trace.TraceInformation(response);
Assert.IsTrue(response.Contains("<PongResult>"));
}
}

[TestMethod]
public async Task AssertThatTheOrdinaryHandlingAlsoWorksAsync()
{
Expand Down
16 changes: 16 additions & 0 deletions src/SoapCore.Tests/SoapMessageProcessor/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.IO;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -22,6 +25,18 @@ public void ConfigureServices(IServiceCollection services)
{
return Message.CreateMessage(MessageVersion.Soap11, "none");
}
else if (httpcontext.Request.Path.Value.Contains("ServiceWithPongProcessor.svc"))
{
var msg = await next(message);
var reader = msg.GetReaderAtBodyContents();

var content = await reader.ReadOuterXmlAsync();

var ms = new MemoryStream(Encoding.UTF8.GetBytes(content.Replace("Ping", "Pong")));
var xmlReader = XmlReader.Create(ms);

return Message.CreateMessage(msg.Version, null, xmlReader);
}
else
{
return await next(message);
Expand All @@ -37,6 +52,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
app.UseEndpoints(x =>
{
x.UseSoapEndpoint<TestService>("/ServiceWithProcessor.svc", new SoapEncoderOptions(), SoapSerializer.DataContractSerializer);
x.UseSoapEndpoint<TestService>("/ServiceWithPongProcessor.svc", new SoapEncoderOptions(), SoapSerializer.DataContractSerializer);
x.UseSoapEndpoint<TestService>("/Service.svc", new SoapEncoderOptions(), SoapSerializer.DataContractSerializer);
});
}
Expand Down
85 changes: 51 additions & 34 deletions src/SoapCore.Tests/Wsdl/WsdlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,35 @@ public class WsdlTests

private IWebHost _host;

[TestMethod]
public async Task CheckBindingAndPortName()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckBindingAndPortName(SoapSerializer soapSerializer)
{
var wsdl = await GetWsdlFromMetaBodyWriter<TaskNoReturnService>(SoapSerializer.XmlSerializer, "MyBinding", "MyPort");
var wsdl = await GetWsdlFromMetaBodyWriter<TaskNoReturnService>(soapSerializer, "BindingName", "PortName");
var root = XElement.Parse(wsdl);

// We should have in the wsdl the definition of a complex type representing the nullable enum
var bindingElements = GetElements(root, _wsdlSchema + "binding").Where(a => a.Attribute("name")?.Value.Equals("MyBinding") == true).ToArray();
var bindingElements = GetElements(root, _wsdlSchema + "binding").Where(a => a.Attribute("name")?.Value.Equals("BindingName") == true).ToArray();
bindingElements.ShouldNotBeEmpty();

var portElements = GetElements(root, _wsdlSchema + "port").Where(a => a.Attribute("name")?.Value.Equals("MyPort") == true).ToArray();
var portElements = GetElements(root, _wsdlSchema + "port").Where(a => a.Attribute("name")?.Value.Equals("PortName") == true).ToArray();
portElements.ShouldNotBeEmpty();
}

[TestMethod]
public async Task CheckDefaultBindingAndPortName()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer, "_soap")]
[DataRow(SoapSerializer.DataContractSerializer, "")]
public async Task CheckDefaultBindingAndPortName(SoapSerializer soapSerializer, string bindingSuffix)
{
var wsdl = await GetWsdlFromMetaBodyWriter<TaskNoReturnService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<TaskNoReturnService>(soapSerializer);
var root = XElement.Parse(wsdl);

// We should have in the wsdl the definition of a complex type representing the nullable enum
var bindingElements = GetElements(root, _wsdlSchema + "binding").Where(a => a.Attribute("name")?.Value.Equals("BasicHttpBinding_soap") == true).ToArray();
var bindingElements = GetElements(root, _wsdlSchema + "binding").Where(a => a.Attribute("name")?.Value.Equals("BasicHttpBinding" + bindingSuffix) == true).ToArray();
bindingElements.ShouldNotBeEmpty();

var portElements = GetElements(root, _wsdlSchema + "port").Where(a => a.Attribute("name")?.Value.Equals("BasicHttpBinding_soap") == true).ToArray();
var portElements = GetElements(root, _wsdlSchema + "port").Where(a => a.Attribute("name")?.Value.Equals("BasicHttpBinding" + bindingSuffix) == true).ToArray();
portElements.ShouldNotBeEmpty();
}

Expand Down Expand Up @@ -440,13 +444,15 @@ public void CheckDictionaryTypeDataContract()
Assert.IsNotNull(myStringElement);
}

[TestMethod]
public async Task CheckStringArrayNameWsdl()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckStringArrayNameWsdl(SoapSerializer soapSerializer)
{
//StartService(typeof(StringListService));
//var wsdl = GetWsdl();
//StopServer();
var wsdl = await GetWsdlFromMetaBodyWriter<StringListService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<StringListService>(soapSerializer);
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);

Expand Down Expand Up @@ -476,13 +482,15 @@ public async Task CheckStringArrayNameWsdl()
Assert.IsTrue(matched);
}

[TestMethod]
public async Task CheckComplexTypeAndOutParameterWsdl()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckComplexTypeAndOutParameterWsdl(SoapSerializer soapSerializer)
{
//StartService(typeof(StringListService));
//var wsdl = GetWsdl();
//StopServer();
var wsdl = await GetWsdlFromMetaBodyWriter<ComplexTypeAndOutParameterService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<ComplexTypeAndOutParameterService>(soapSerializer);
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);

Expand All @@ -507,10 +515,12 @@ public async Task CheckComplexTypeAndOutParameterWsdl()
Assert.IsNotNull(testElementMessage);
}

[TestMethod]
public async Task CheckUnqualifiedMembersService()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckUnqualifiedMembersService(SoapSerializer soapSerializer)
{
var wsdl = await GetWsdlFromMetaBodyWriter<UnqualifiedMembersService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<TaskNoReturnService>(soapSerializer, "BindingName", "PortName");
Trace.TraceInformation(wsdl);

var root = XElement.Parse(wsdl);
Expand All @@ -525,13 +535,15 @@ public async Task CheckUnqualifiedMembersService()
Assert.IsTrue(allNeededAreQualified);
}

[TestMethod]
public async Task CheckDateTimeOffsetServiceWsdl()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckDateTimeOffsetServiceWsdl(SoapSerializer soapSerializer)
{
var nm = Namespaces.CreateDefaultXmlNamespaceManager();
string systemNs = "http://schemas.datacontract.org/2004/07/System";

var wsdl = await GetWsdlFromMetaBodyWriter<DateTimeOffsetService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<DateTimeOffsetService>(soapSerializer);
var root = XElement.Parse(wsdl);
var responseDateElem = root.XPathSelectElement($"//xsd:element[@name='MethodResponse']/xsd:complexType/xsd:sequence/xsd:element[@name='MethodResult']", nm);
Assert.IsTrue(responseDateElem.ToString().Contains(systemNs));
Expand All @@ -544,10 +556,12 @@ public async Task CheckDateTimeOffsetServiceWsdl()
Assert.IsNull(dayOfYearElem);
}

[TestMethod]
public async Task CheckXmlSchemaProviderTypeServiceWsdl()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckXmlSchemaProviderTypeServiceWsdl(SoapSerializer soapSerializer)
{
var wsdl = await GetWsdlFromMetaBodyWriter<XmlSchemaProviderTypeService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<XmlSchemaProviderTypeService>(soapSerializer);
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);

Expand All @@ -558,10 +572,12 @@ public async Task CheckXmlSchemaProviderTypeServiceWsdl()
Assert.IsNotNull(responseDateElem);
}

[TestMethod]
public async Task CheckTestMultipleTypesServiceWsdl()
[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
[DataRow(SoapSerializer.DataContractSerializer)]
public async Task CheckTestMultipleTypesServiceWsdl(SoapSerializer soapSerializer)
{
var wsdl = await GetWsdlFromMetaBodyWriter<TestMultipleTypesService>(SoapSerializer.XmlSerializer);
var wsdl = await GetWsdlFromMetaBodyWriter<TestMultipleTypesService>(soapSerializer);
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);
}
Expand Down Expand Up @@ -639,7 +655,7 @@ public void CheckFieldMembersASMX()
Assert.AreEqual(5, propElementsCount);
}

[TestMethod]
[DataTestMethod]
public async Task CheckXmlAnnotatedTypeServiceWsdl()
{
var wsdl = await GetWsdlFromMetaBodyWriter<XmlModelsService>(SoapSerializer.XmlSerializer);
Expand Down Expand Up @@ -685,7 +701,7 @@ public async Task CheckXmlAnnotatedTypeServiceWsdl()
Assert.IsNotNull(propAnonAttribute);
}

[TestMethod]
[DataTestMethod]
public async Task CheckXmlAnnotatedChoiceReturnServiceWsdl()
{
var wsdl = await GetWsdlFromMetaBodyWriter<XmlAnnotatedChoiceReturnService>(SoapSerializer.XmlSerializer);
Expand Down Expand Up @@ -716,7 +732,7 @@ public async Task CheckXmlAnnotatedChoiceReturnServiceWsdl()
Assert.IsNotNull(choiceComplexTypeElement.XPathSelectElement("//xsd:complexType/xsd:sequence/xsd:choice/xsd:element[@name='second' and @type='xsd:string']", nm));
}

[TestMethod]
[DataTestMethod]
public async Task CheckMessageHeadersServiceWsdl()
{
var wsdl = await GetWsdlFromMetaBodyWriter<MessageHeadersService>(SoapSerializer.XmlSerializer);
Expand Down Expand Up @@ -774,12 +790,13 @@ private async Task<string> GetWsdlFromMetaBodyWriter<T>(SoapSerializer serialize
var service = new ServiceDescription(typeof(T));
var baseUrl = "http://tempuri.org/";
var xmlNamespaceManager = Namespaces.CreateDefaultXmlNamespaceManager();
var defaultBindingName = !string.IsNullOrWhiteSpace(bindingName) ? bindingName : "BasicHttpBinding";
var bodyWriter = serializer == SoapSerializer.DataContractSerializer
? new MetaWCFBodyWriter(service, baseUrl, "BasicHttpBinding", false) as BodyWriter
: new MetaBodyWriter(service, baseUrl, xmlNamespaceManager, "BasicHttpBinding", new[] { new SoapBindingInfo(MessageVersion.None, bindingName, portName) }) as BodyWriter;
? 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) }) as BodyWriter;
var encoder = new SoapMessageEncoder(MessageVersion.Soap12WSAddressingAugust2004, System.Text.Encoding.UTF8, XmlDictionaryReaderQuotas.Max, false, true, false, null, bindingName, portName);
var responseMessage = Message.CreateMessage(encoder.MessageVersion, null, bodyWriter);
responseMessage = new MetaMessage(responseMessage, service, xmlNamespaceManager, "BasicHttpBinding", false);
responseMessage = new MetaMessage(responseMessage, service, xmlNamespaceManager, defaultBindingName, false);

using (var memoryStream = new MemoryStream())
{
Expand Down
23 changes: 23 additions & 0 deletions src/SoapCore/CustomStringWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.IO;
using System.Text;

namespace SoapCore
{
public class CustomStringWriter : StringWriter
{
private readonly Encoding _encoding;

public CustomStringWriter(Encoding encoding)
{
_encoding = encoding;
}

public override Encoding Encoding
{
get
{
return _encoding;
}
}
}
}
Loading

0 comments on commit 5e7979e

Please sign in to comment.