Skip to content

Commit

Permalink
Merge pull request #955 from bfcrmimick/Issue908
Browse files Browse the repository at this point in the history
XmlNode/XmlElement as an Input Parameter
  • Loading branch information
andersjonsson committed Aug 17, 2023
2 parents baf9653 + 029aecf commit 18d041a
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/SoapCore.Tests/ITestService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.AspNetCore.Mvc;
using SoapCore.Tests.Model;

Expand Down Expand Up @@ -94,5 +95,11 @@ public interface ITestService
[ServiceKnownType("GetKnownTypes", typeof(TestServiceKnownTypesProvider))]
[OperationContract]
IComplexTreeModelInput GetComplexModelInputFromKnownTypeProvider(ComplexModelInput value);

[OperationContract]
XmlElement ReturnXmlElement();

[OperationContract]
XmlElement XmlElementInput(XmlElement input);
}
}
21 changes: 21 additions & 0 deletions src/SoapCore.Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.AspNetCore.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SoapCore.Tests.Model;
Expand Down Expand Up @@ -226,6 +227,26 @@ public void ComplexModelInputFromServiceKnownTypeProvider()
Assert.AreEqual(input.StringProperty, output.Item.StringProperty);
}

[TestMethod]
public void ReturnXmlElement()
{
var client = CreateClient();
var output = client.ReturnXmlElement();
Assert.IsInstanceOfType(output, typeof(XmlElement));
Assert.AreEqual(output.OuterXml, "<TestXml xmlns=\"\" />");
}

[TestMethod]
public void XmlElemetInput()
{
var client = CreateClient();
XmlDocument xdInput = new XmlDocument();
xdInput.LoadXml("<XmlTestInput/>");
var output = client.XmlElementInput(xdInput.DocumentElement);
Assert.IsInstanceOfType(output, typeof(XmlElement));
Assert.IsTrue(output.OuterXml.Contains("Success"));
}

[TestMethod]
public void ThrowsFaultException()
{
Expand Down
23 changes: 23 additions & 0 deletions src/SoapCore.Tests/TestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.ServiceModel;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.AspNetCore.Mvc;
using SoapCore.Tests.Model;

Expand Down Expand Up @@ -196,5 +197,27 @@ public IComplexTreeModelInput GetComplexModelInputFromKnownTypeProvider(ComplexM
Item = value
};
}

public XmlElement ReturnXmlElement()
{
XmlDocument xdOutput = new XmlDocument();
xdOutput.LoadXml("<TestXml/>");
return xdOutput.DocumentElement;
}

public XmlElement XmlElementInput(XmlElement input)
{
XmlDocument xdOutput = new XmlDocument();
if (input != null)
{
xdOutput.LoadXml("<Success/>");
}
else
{
xdOutput.LoadXml("<Failed/>");
}

return xdOutput.DocumentElement;
}
}
}
18 changes: 18 additions & 0 deletions src/SoapCore.Tests/XmlNodeInputOutput/IXmlNodeInputOutput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using System.Xml;

namespace SoapCore.Tests.XmlNodeInputOutput
{
[ServiceContract]
public interface IXmlNodeInputOutput
{
[OperationContract]
XmlElement ProcessRequest(string login, string password, XmlElement requestXml);

[OperationContract]
XmlElement GetRequest();
}
}
34 changes: 34 additions & 0 deletions src/SoapCore.Tests/XmlNodeInputOutput/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;

namespace SoapCore.Tests.XmlNodeInputOutput
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSoapCore();
services.TryAddSingleton<IXmlNodeInputOutput, XmlNodeInputOutput>();
services.AddMvc();
}

public void Configure(IApplicationBuilder app)
{
app.UseRouting();

app.UseEndpoints(x =>
{
x.UseSoapEndpoint<IXmlNodeInputOutput>("/Service.svc", new SoapEncoderOptions(), SoapSerializer.DataContractSerializer);
x.UseSoapEndpoint<IXmlNodeInputOutput>("/Service.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
});
}
}
}
35 changes: 35 additions & 0 deletions src/SoapCore.Tests/XmlNodeInputOutput/XmlNodeInputOutput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace SoapCore.Tests.XmlNodeInputOutput
{
public class XmlNodeInputOutput : IXmlNodeInputOutput
{
public XmlNodeInputOutput()
{
}

public XmlElement ProcessRequest(string login, string password, XmlElement requestXml)
{
if (password == "Password")
{
return requestXml;
}
else
{
XmlDocument xdError = new XmlDocument();
xdError.LoadXml("<Error><Message>Incorrect Password</Message></Error>");
return xdError.DocumentElement;
}
}

public XmlElement GetRequest()
{
XmlDocument xdResponse = new XmlDocument();
xdResponse.LoadXml("<Response><Message>A response</Message></Response>");
return xdResponse.DocumentElement;
}
}
}
78 changes: 78 additions & 0 deletions src/SoapCore.Tests/XmlNodeInputOutput/XmlNodeInputOutputTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace SoapCore.Tests.XmlNodeInputOutput
{
/*
* This test refers to issue https://github.com/DigDes/SoapCore/issues/908
* User has a service with an XmlNode parameter and the value sent to the function is always null.
*/

[TestClass]
public class XmlNodeInputOutputTests
{
[TestMethod]
public async Task SendXmlInputGetXmlOutputAsync()
{
string xmlInput = "<Request><Input>Hello</Input><Type>Test</Type></Request>",
strLogin = "Login",
strPassword = "Password";
var body = $@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"">
<soapenv:Body>
<ProcessRequest xmlns=""http://tempuri.org/"">
<login>{strLogin}</login>
<password>{strPassword}</password>
<requestXml>{xmlInput}</requestXml>
</ProcessRequest>
</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("/Service.svc").AddHeader("SOAPAction", @"""ProcessRequest""").And(msg => msg.Content = content).PostAsync().Result)
{
res.EnsureSuccessStatusCode();

var response = await res.Content.ReadAsStringAsync();

//XML comes back as formatted, need to clear any newlines and replace any double spaces
Assert.IsTrue(response.Replace(System.Environment.NewLine, string.Empty).Replace(" ", string.Empty).Contains(xmlInput));
}
}

[TestMethod]
public async Task GetXmlOutputAsync()
{
var body = $@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"">
<soapenv:Body>
<GetRequest xmlns=""http://tempuri.org/"">
</GetRequest>
</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("/Service.svc").AddHeader("SOAPAction", @"""GetRequest""").And(msg => msg.Content = content).PostAsync().Result)
{
res.EnsureSuccessStatusCode();

var response = await res.Content.ReadAsStringAsync();
Assert.IsTrue(response.Contains("A response"));
}
}

private TestServer CreateTestHost()
{
var webHostBuilder = new WebHostBuilder()
.UseStartup<Startup>();
return new TestServer(webHostBuilder);
}
}
}
12 changes: 11 additions & 1 deletion src/SoapCore/SerializerHelper.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.CSharp;

Expand Down Expand Up @@ -37,7 +39,7 @@ public object DeserializeInputParameter(
xmlReader.MoveToStartElement(parameterName, parameterNs);

if (xmlReader.IsStartElement(parameterName, parameterNs))
{
{
switch (_serializer)
{
case SoapSerializer.XmlSerializer:
Expand Down Expand Up @@ -88,6 +90,14 @@ private static object DeserializeObject(System.Xml.XmlDictionaryReader xmlReader
{
xmlReader.Read();
return new MemoryStream(xmlReader.ReadContentAsBase64(), false);
}

if (elementType == typeof(XmlElement) || elementType == typeof(XmlNode))
{
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlReader.ReadInnerXml());
var xmlNode = xmlDoc.FirstChild;
return xmlNode;
}

return serializer.Deserialize(xmlReader);
Expand Down

0 comments on commit 18d041a

Please sign in to comment.