Skip to content

Commit

Permalink
Merge pull request #424 from DigDes/develop
Browse files Browse the repository at this point in the history
Merge 1.0.0.2-alpha
  • Loading branch information
kotovaleksandr authored Feb 3, 2020
2 parents 7452a6d + 5121ac9 commit 248b1b1
Show file tree
Hide file tree
Showing 12 changed files with 441 additions and 43 deletions.
33 changes: 33 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/ICollectionDataContractService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace SoapCore.Tests.Wsdl.Services
{
[ServiceContract]
public interface ICollectionDataContractService
{
[OperationContract]
CollectionDataContractService.MyList<string> ListStrings();

[OperationContract]
CollectionDataContractService.MyList<CollectionDataContractService.MyType> ListMyTypes();
}

public class CollectionDataContractService : ICollectionDataContractService
{
public MyList<string> ListStrings() => throw new NotImplementedException();
public MyList<MyType> ListMyTypes() => throw new NotImplementedException();

[CollectionDataContract(Namespace = "http://testnamespace.org", Name = "My{0}List", ItemName = "MyItem")]
public class MyList<T> : List<T>
{
}

public class MyType
{
public string MyProperty { get; set; }
}
}
}
20 changes: 20 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/IDatetimeOffsetService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.ServiceModel;

namespace SoapCore.Tests.Wsdl.Services
{
[ServiceContract]
public interface IDatetimeOffsetService
{
[OperationContract]
DateTimeOffset Method(DateTimeOffset model);
}

public class DateTimeOffsetService : IDatetimeOffsetService
{
public DateTimeOffset Method(DateTimeOffset model)
{
throw new NotImplementedException();
}
}
}
54 changes: 54 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/ITestMultipleTypesService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Data;
using System.ServiceModel;
using System.Xml.Linq;

namespace SoapCore.Tests.Wsdl.Services
{
[ServiceContract]
public interface ITestMultipleTypesService
{
[OperationContract]
DataTable GetDataTable(DataTable input);

[OperationContract]
System.Xml.Linq.XElement GetXElement(System.Xml.Linq.XElement input);

[OperationContract]
DateTimeOffset GetDateTimeOffset(DateTimeOffset input);

[OperationContract]
string GetString(string input);

[OperationContract]
MyClass GetMyClass(MyClass input);
}

public class TestMultipleTypesService : ITestMultipleTypesService
{
public DataTable GetDataTable(DataTable input)
{
throw new NotImplementedException();
}

public DateTimeOffset GetDateTimeOffset(DateTimeOffset input)
{
throw new NotImplementedException();
}

public string GetString(string input)
{
throw new NotImplementedException();
}

public XElement GetXElement(XElement input)
{
throw new NotImplementedException();
}

public MyClass GetMyClass(MyClass input)
{
return input;
}
}
}
30 changes: 30 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/IXmlSchemaProviderTypeService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Data;
using System.ServiceModel;
using System.Xml.Linq;

namespace SoapCore.Tests.Wsdl.Services
{
[ServiceContract]
public interface IXmlSchemaProviderTypeService
{
[OperationContract]
DataTable GetDataTable(DataTable input);

[OperationContract]
System.Xml.Linq.XElement GetXElement(System.Xml.Linq.XElement input);
}

public class XmlSchemaProviderTypeService : IXmlSchemaProviderTypeService
{
public DataTable GetDataTable(DataTable input)
{
throw new NotImplementedException();
}

public XElement GetXElement(XElement input)
{
throw new NotImplementedException();
}
}
}
13 changes: 13 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/MyClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Data;
using System.ServiceModel;
using System.Xml.Linq;

namespace SoapCore.Tests.Wsdl.Services
{
public class MyClass
{
public string StringProperty { get; set; }
public int IntProperty { get; set; }
}
}
81 changes: 80 additions & 1 deletion src/SoapCore.Tests/Wsdl/WsdlTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.ServiceModel.Channels;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
Expand All @@ -12,6 +14,9 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;
using SoapCore.MessageEncoder;
using SoapCore.Meta;
using SoapCore.ServiceModel;
using SoapCore.Tests.Wsdl.Services;

namespace SoapCore.Tests.Wsdl
Expand Down Expand Up @@ -168,10 +173,66 @@ public void CheckEnumList()
Assert.AreEqual("unbounded", element.Attribute("maxOccurs").Value);
}

[TestMethod]
public void CheckCollectionDataContract()
{
StartService(typeof(CollectionDataContractService));
var wsdl = GetWsdl();
StopServer();

var root = XElement.Parse(wsdl);

var listStringsResult = GetElements(root, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("name")?.Value.Equals("ListStringsResult") == true);
Assert.IsNotNull(listStringsResult);
Assert.AreEqual("http://testnamespace.org", listStringsResult.Attribute(XNamespace.Xmlns + "q1").Value);
Assert.AreEqual("q1:MystringList", listStringsResult.Attribute("type").Value);

var myStringList = GetElements(root, _xmlSchema + "complexType").SingleOrDefault(a => a.Attribute("name")?.Value.Equals("MystringList") == true);
Assert.IsNotNull(myStringList);

var myStringElement = GetElements(myStringList, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("name")?.Value.Equals("MyItem") == true);
Assert.IsNotNull(myStringElement);

var listMyTypesResult = GetElements(root, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("name")?.Value.Equals("ListMyTypesResult") == true);
Assert.IsNotNull(listMyTypesResult);
Assert.AreEqual("http://testnamespace.org", listMyTypesResult.Attribute(XNamespace.Xmlns + "q2").Value);
Assert.AreEqual("q2:MyMyTypeList", listMyTypesResult.Attribute("type").Value);

var myMyTypeList = GetElements(root, _xmlSchema + "complexType").SingleOrDefault(a => a.Attribute("name")?.Value.Equals("MyMyTypeList") == true);
Assert.IsNotNull(myMyTypeList);

var myMyTypeElement = GetElements(myMyTypeList, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("name")?.Value.Equals("MyItem") == true);
Assert.IsNotNull(myMyTypeElement);
}

[TestMethod]
public async Task CheckDateTimeOffsetServiceWsdl()
{
var wsdl = await GetWsdlFromMetaBodyWriter<DateTimeOffsetService>();
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);
}

[TestMethod]
public async Task CheckXmlSchemaProviderTypeServiceWsdl()
{
var wsdl = await GetWsdlFromMetaBodyWriter<XmlSchemaProviderTypeService>();
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);
}

[TestMethod]
public async Task CheckTestMultipleTypesServiceWsdl()
{
var wsdl = await GetWsdlFromMetaBodyWriter<TestMultipleTypesService>();
Trace.TraceInformation(wsdl);
Assert.IsNotNull(wsdl);
}

[TestCleanup]
public void StopServer()
{
_host.StopAsync();
_host?.StopAsync();
}

private string GetWsdl()
Expand All @@ -187,6 +248,24 @@ private string GetWsdl()
}
}

private async Task<string> GetWsdlFromMetaBodyWriter<T>()
{
var service = new ServiceDescription(typeof(T));
var baseUrl = "http://tempuri.org/";
var bodyWriter = new MetaBodyWriter(service, baseUrl, null);
var encoder = new SoapMessageEncoder(MessageVersion.Soap12WSAddressingAugust2004, System.Text.Encoding.UTF8, XmlDictionaryReaderQuotas.Max, false, true);
var responseMessage = Message.CreateMessage(encoder.MessageVersion, null, bodyWriter);
responseMessage = new MetaMessage(responseMessage, service, null);

var memoryStream = new MemoryStream();
await encoder.WriteMessageAsync(responseMessage, memoryStream);
memoryStream.Position = 0;

var streamReader = new StreamReader(memoryStream);
var result = streamReader.ReadToEnd();
return result;
}

private void StartService(Type serviceType)
{
Task.Run(() =>
Expand Down
117 changes: 117 additions & 0 deletions src/SoapCore/Meta/BodyWriterExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace SoapCore.Meta
{
public static class BodyWriterExtensions
{
//switches to easily revert to previous behaviour if there is a problem
private static bool useXmlSchemaProvider = true;
private static bool useXmlReflectionImporter = false;
public static bool TryAddSchemaTypeFromXmlSchemaProviderAttribute(this XmlDictionaryWriter writer, Type type, string name, SoapSerializer serializer)
{
if (!useXmlSchemaProvider && !useXmlReflectionImporter)
{
return false;
}

if (useXmlReflectionImporter)
{
var schemas = new XmlSchemas();
var xmlImporter = new XmlReflectionImporter();
var exporter = new XmlSchemaExporter(schemas);

var xmlTypeMapping = xmlImporter.ImportTypeMapping(type, new XmlRootAttribute() { ElementName = name });
exporter.ExportTypeMapping(xmlTypeMapping);
schemas.Compile(null, true);

var memoryStream = new MemoryStream();
foreach (XmlSchema schema in schemas)
{
schema.Write(memoryStream);
}
memoryStream.Position = 0;

var streamReader = new StreamReader(memoryStream);
var result = streamReader.ReadToEnd();

var doc = new XmlDocument();
doc.LoadXml(result);
doc.DocumentElement.WriteContentTo(writer);

return true;
}

var xmlSchemaSet = new XmlSchemaSet();
var xmlSchemaProviderAttribute = type.GetCustomAttribute<XmlSchemaProviderAttribute>(true);
if (xmlSchemaProviderAttribute != null && true)
{
XmlSchema schema = new XmlSchema();
if (xmlSchemaProviderAttribute.IsAny)
{
//MetaWCFBodyWriter usage....
//writer.WriteAttributeString("name", name);
//writer.WriteAttributeString("nillable", "true");
//writer.WriteStartElement("xs", "complexType", Namespaces.XMLNS_XSD);
//writer.WriteStartElement("xs", "sequence", Namespaces.XMLNS_XSD);
//writer.WriteStartElement("xs", "any", Namespaces.XMLNS_XSD);
//writer.WriteAttributeString("minOccurs", "0");
//writer.WriteAttributeString("processContents", "lax");
//writer.WriteEndElement();
//writer.WriteEndElement();
//writer.WriteEndElement();
var sequence = new XmlSchemaSequence();
sequence.Items.Add(new XmlSchemaAny() { ProcessContents = XmlSchemaContentProcessing.Lax });
var complex = new XmlSchemaComplexType()
{
Particle = sequence
};
var element = new XmlSchemaElement()
{
MinOccurs = 0,
MaxOccurs = 1,
Name = name,
IsNillable = serializer == SoapSerializer.DataContractSerializer ? true : false,
SchemaType = complex
};
schema.Items.Add(element);
}
else
{
var methodInfo = type.GetMethod(xmlSchemaProviderAttribute.MethodName, BindingFlags.Static | BindingFlags.Public);
var xmlSchemaType = (XmlSchemaType)methodInfo.Invoke(null, new object[] { xmlSchemaSet });
var element = new XmlSchemaElement()
{
MinOccurs = 0,
MaxOccurs = 1,
Name = name,
SchemaType = xmlSchemaType
};
schema.Items.Add(element);
}

var memoryStream = new MemoryStream();
schema.Write(memoryStream);
memoryStream.Position = 0;

var streamReader = new StreamReader(memoryStream);
var result = streamReader.ReadToEnd();

var doc = new XmlDocument();
doc.LoadXml(result);
doc.DocumentElement.WriteContentTo(writer);

return true;
}

return false;
}

}
}
Loading

0 comments on commit 248b1b1

Please sign in to comment.