Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle DataContract.Name on generic type #1068

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading