diff --git a/src/SoapCore.Tests/Wsdl/Services/ComplexTypeAnonymous.cs b/src/SoapCore.Tests/Wsdl/Services/ComplexTypeAnonymous.cs new file mode 100644 index 00000000..536c41e5 --- /dev/null +++ b/src/SoapCore.Tests/Wsdl/Services/ComplexTypeAnonymous.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace SoapCore.Tests.Wsdl.Services +{ + [XmlType(AnonymousType = true)] + public class ComplexTypeAnonymous + { + public int IntProperty { get; set; } + [XmlElement(ElementName = "stringprop")] + public string StringProperty { get; set; } + [XmlElement(ElementName = "mybytes")] + public byte[] ByteArrayProperty { get; set; } + + public Guid MyGuid { get; set; } + + public List StringList { get; set; } + + public List IntList { get; set; } + } +} diff --git a/src/SoapCore.Tests/Wsdl/Services/IComplexAnonymousListService.cs b/src/SoapCore.Tests/Wsdl/Services/IComplexAnonymousListService.cs new file mode 100644 index 00000000..3190016a --- /dev/null +++ b/src/SoapCore.Tests/Wsdl/Services/IComplexAnonymousListService.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel; +using System.Text; +using System.Threading.Tasks; + +namespace SoapCore.Tests.Wsdl.Services +{ + [ServiceContract] + public interface IComplexAnonymousListService + { + [OperationContract] + List Test(); + } + + public class ComplexAnonymousListService : IComplexAnonymousListService + { + public List Test() => throw new NotImplementedException(); + } +} diff --git a/src/SoapCore.Tests/Wsdl/WsdlTests.cs b/src/SoapCore.Tests/Wsdl/WsdlTests.cs index d77921be..04e66aaa 100644 --- a/src/SoapCore.Tests/Wsdl/WsdlTests.cs +++ b/src/SoapCore.Tests/Wsdl/WsdlTests.cs @@ -1239,6 +1239,52 @@ public void CheckComplexBaseTypeServiceWsdl() Assert.IsNotNull(listDerivedType); } + [DataTestMethod] + [DataRow(SoapSerializer.XmlSerializer)] + public async Task CheckComplexAnonymousTypeListWsdl(SoapSerializer soapSerializer) + { + var wsdl = await GetWsdlFromMetaBodyWriter(soapSerializer); + Trace.TraceInformation(wsdl); + Assert.IsNotNull(wsdl); + + var root = XElement.Parse(wsdl); + + // Check complexType exists for xmlserializer meta + var testResultElement = GetElements(root, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("type") != null && a.Attribute("name")?.Value.Equals("TestResult") == true); + Assert.IsNotNull(testResultElement); + + // Now check if we can match the array type up with it's declaration + var split = testResultElement.Attribute("type").Value.Split(':'); + var typeNamespace = testResultElement.GetNamespaceOfPrefix(split[0]); + + var matchingSchema = GetElements(root, _xmlSchema + "schema").Where(schema => schema.Attribute("targetNamespace")?.Value.Equals(typeNamespace.NamespaceName) == true); + Assert.IsTrue(matchingSchema.Count() > 0); + + var matched = false; + XElement matchingComplexType = null; + foreach (var schema in matchingSchema) + { + matchingComplexType = GetElements(schema, _xmlSchema + "complexType").SingleOrDefault(a => a.Attribute("name")?.Value.Equals(split[1]) == true); + if (matchingComplexType != null) + { + matched = true; + } + } + + Assert.IsTrue(matched); + + // The complex type is an array with a single element, which is an anonymous complex type + var arrayElement = matchingComplexType.Element(_xmlSchema + "sequence")?.Element(_xmlSchema + "element"); + Assert.IsNotNull(arrayElement); + + // The element needs a name and a complex type + var nameAttribute = arrayElement.Attribute("name"); + Assert.IsFalse(string.IsNullOrEmpty(nameAttribute.Value)); + + var arrayElementType = arrayElement.Element(_xmlSchema + "complexType"); + Assert.IsNotNull(arrayElementType); + } + [TestCleanup] public void StopServer() { @@ -1281,6 +1327,7 @@ private async Task GetWsdlFromMetaBodyWriter(SoapSerializer serialize var service = new ServiceDescription(typeof(T), false); var baseUrl = "http://tempuri.org/"; var xmlNamespaceManager = Namespaces.CreateDefaultXmlNamespaceManager(useMicrosoftGuid); + xmlNamespaceManager.AddNamespace("tns", service.GeneralContract.Namespace); 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) }, new DefaultWsdlOperationNameGenerator()) as BodyWriter diff --git a/src/SoapCore/Meta/MetaBodyWriter.cs b/src/SoapCore/Meta/MetaBodyWriter.cs index 8e627186..ecc71a3d 100644 --- a/src/SoapCore/Meta/MetaBodyWriter.cs +++ b/src/SoapCore/Meta/MetaBodyWriter.cs @@ -1240,6 +1240,11 @@ private void AddSchemaType(XmlDictionaryWriter writer, TypeToBuild toBuild, stri } else if (toBuild.IsAnonumous) { + if (string.IsNullOrEmpty(name)) + { + name = typeName; + } + writer.WriteAttributeString("name", name); WriteQualification(writer, isUnqualified); AddSchemaComplexType(writer, newTypeToBuild);