Skip to content

Commit

Permalink
Merge pull request #1068 from navozenko/fix-data-contract-name
Browse files Browse the repository at this point in the history
Handle DataContract.Name on generic type
  • Loading branch information
andersjonsson authored Jun 26, 2024
2 parents 17b862f + 40447ca commit 142a64b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 6 deletions.
35 changes: 35 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/IGenericDataContractService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace SoapCore.Tests.Wsdl.Services
{
[ServiceContract]
public interface IGenericDataContractService
{
[OperationContract]
GenericDataContractService.MyType<string> TestString();

[OperationContract]
GenericDataContractService.MyType<GenericDataContractService.MyArg> TestMyArg();
}

public class GenericDataContractService : IGenericDataContractService
{
public MyType<string> TestString() => throw new NotImplementedException();

public MyType<MyArg> TestMyArg() => throw new NotImplementedException();

[DataContract(Name = "My{0}Type", Namespace = "http://testnamespace.org")]
public class MyType<T>
{
[DataMember]
public T Value { get; set; }
}

public class MyArg
{
public string Value { get; set; }
}
}
}
20 changes: 20 additions & 0 deletions src/SoapCore.Tests/Wsdl/WsdlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,26 @@ public void CheckCollectionDataContract()
Assert.IsNotNull(myMyTypeElement);
}

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

var root = XElement.Parse(wsdl);

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

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

[TestMethod]
public void CheckDictionaryTypeDataContract()
{
Expand Down
31 changes: 25 additions & 6 deletions src/SoapCore/Meta/MetaWCFBodyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1554,14 +1554,34 @@ private void WriteComplexElementType(XmlDictionaryWriter writer, string typeName

private string GetTypeName(Type type)
{
var dataContractAttribute = type.GetCustomAttribute<DataContractAttribute>();

if (type.IsGenericType && !type.IsArray && !typeof(IEnumerable).IsAssignableFrom(type))
{
var genericTypes = GetGenericTypes(type);
var genericTypeNames = genericTypes.Select(a => GetTypeName(a));
if (dataContractAttribute != null && dataContractAttribute.IsNameSetExplicitly)
{
var typeName = dataContractAttribute.Name;
var genericTypes = GetGenericTypes(type);
var genericTypeNames = genericTypes
.Select(genericType =>
{
var (name, _) = ResolveSystemType(genericType);
return string.IsNullOrEmpty(name) ? GetTypeName(genericType) : name;
})
.ToArray();

typeName = string.Format(typeName, genericTypeNames);
return typeName;
}
else
{
var genericTypes = GetGenericTypes(type);
var genericTypeNames = genericTypes.Select(a => GetTypeName(a));

var typeName = ReplaceGenericNames(type.Name);
typeName = typeName + "Of" + string.Concat(genericTypeNames);
return typeName;
var typeName = ReplaceGenericNames(type.Name);
typeName = typeName + "Of" + string.Concat(genericTypeNames);
return typeName;
}
}

if (type.IsArray)
Expand Down Expand Up @@ -1598,7 +1618,6 @@ private string GetTypeName(Type type)
}

// Make use of DataContract attribute, if set, as it may contain a Name override
var dataContractAttribute = type.GetCustomAttribute<DataContractAttribute>();
if (dataContractAttribute != null && dataContractAttribute.IsNameSetExplicitly)
{
return dataContractAttribute.Name;
Expand Down

0 comments on commit 142a64b

Please sign in to comment.