Skip to content
Open
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
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 IShouldSerializeTypeMemberService
{
[OperationContract]
TypeWithShouldSerializeMember Method();
}

public class ShouldSerializeTypeMemberService : IShouldSerializeTypeMemberService
{
public TypeWithShouldSerializeMember Method()
{
throw new NotImplementedException();
}
}
}
14 changes: 14 additions & 0 deletions src/SoapCore.Tests/Wsdl/Services/TypeWithShouldSerializeMember.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace SoapCore.Tests.Wsdl.Services
{
public class TypeWithShouldSerializeMember
{
public int IntProperty { get; set; }

public int? OptionalIntProperty { get; set; }

public bool ShouldSerializeOptionalIntProperty()
{
return OptionalIntProperty.HasValue;
}
}
}
23 changes: 23 additions & 0 deletions src/SoapCore.Tests/Wsdl/WsdlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,29 @@ public async Task CheckXmlAttributeSerialization(SoapSerializer soapSerializer)
Assert.IsNull(optionalIntAttribute.Attribute("use"));
}

[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
public async Task CheckShouldSerializeMemberSerialization(SoapSerializer soapSerializer)
{
var wsdl = await GetWsdlFromMetaBodyWriter<ShouldSerializeTypeMemberService>(soapSerializer);
Assert.IsNotNull(wsdl);

var root = XElement.Parse(wsdl);

var shouldSerializeType = GetElements(root, _xmlSchema + "complexType").SingleOrDefault(a => a.Attribute("name")?.Value == "TypeWithShouldSerializeMember");
Assert.IsNotNull(shouldSerializeType);

// verify that value types (such as int) have use="required" attribute
var intElement = GetElements(shouldSerializeType, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("name")?.Value == "IntProperty");
Assert.IsTrue(intElement.Attribute("minOccurs").Value == "1");
Assert.IsTrue(intElement.Attribute("maxOccurs").Value == "1");

// verify that if a value type has a ShouldSerialize*() method, it is not marked as required
var optionalIntAttribute = GetElements(shouldSerializeType, _xmlSchema + "element").SingleOrDefault(a => a.Attribute("name")?.Value == "OptionalIntProperty");
Assert.IsTrue(optionalIntAttribute.Attribute("minOccurs").Value == "0");
Assert.IsTrue(optionalIntAttribute.Attribute("maxOccurs").Value == "1");
}

[DataTestMethod]
[DataRow(SoapSerializer.XmlSerializer)]
public async Task CheckSoapHeaderTypes(SoapSerializer soapSerializer)
Expand Down
12 changes: 7 additions & 5 deletions src/SoapCore/Meta/MetaBodyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ private void AddSchemaTypePropertyOrField(XmlDictionaryWriter writer, MemberInfo

bool isOptional = member.HasShouldSerializeMethod(parentTypeToBuild);

AddSchemaType(writer, toBuild, name, isAttribute: true, isUnqualified: isUnqualified, isOptionalAttribute: isOptional);
AddSchemaType(writer, toBuild, name, isAttribute: true, isUnqualified: isUnqualified, isOptional: isOptional);
}
else if (messageBodyMemberAttribute != null)
{
Expand Down Expand Up @@ -1045,7 +1045,9 @@ private void AddSchemaTypePropertyOrField(XmlDictionaryWriter writer, MemberInfo
var hasSpecifiedBoolean = member.DeclaringType.GetProperties()
.Any(p => p.Name == $"{member.Name}Specified" && p.PropertyType == typeof(bool) && p.GetCustomAttribute<XmlIgnoreAttribute>() != null);

AddSchemaType(writer, toBuild, elementNameFromAttribute ?? member.Name ?? parentTypeToBuild.ChildElementName, isArray: createListWithoutProxyType, isListWithoutWrapper: createListWithoutProxyType, isUnqualified: isUnqualified, defaultValue: defaultValue, hasSpecifiedBoolean: hasSpecifiedBoolean);
bool isOptional = member.HasShouldSerializeMethod(parentTypeToBuild);

AddSchemaType(writer, toBuild, elementNameFromAttribute ?? member.Name ?? parentTypeToBuild.ChildElementName, isArray: createListWithoutProxyType, isListWithoutWrapper: createListWithoutProxyType, isUnqualified: isUnqualified, defaultValue: defaultValue, hasSpecifiedBoolean: hasSpecifiedBoolean, isOptional: isOptional);
}
}

Expand All @@ -1065,7 +1067,7 @@ private void AddSchemaType(XmlDictionaryWriter writer, Type type, string name, b
AddSchemaType(writer, new TypeToBuild(type), name, isArray, @namespace, isAttribute, isUnqualified: isUnqualified);
}

private void AddSchemaType(XmlDictionaryWriter writer, TypeToBuild toBuild, string name, bool isArray = false, string @namespace = null, bool isAttribute = false, bool isListWithoutWrapper = false, bool isUnqualified = false, string defaultValue = null, bool isOptionalAttribute = false, bool hasSpecifiedBoolean = false)
private void AddSchemaType(XmlDictionaryWriter writer, TypeToBuild toBuild, string name, bool isArray = false, string @namespace = null, bool isAttribute = false, bool isListWithoutWrapper = false, bool isUnqualified = false, string defaultValue = null, bool isOptional = false, bool hasSpecifiedBoolean = false)
{
var type = toBuild.Type;

Expand Down Expand Up @@ -1165,7 +1167,7 @@ private void AddSchemaType(XmlDictionaryWriter writer, TypeToBuild toBuild, stri
}
else
{
writer.WriteAttributeString("minOccurs", type.IsValueType && defaultValue == null && !hasSpecifiedBoolean ? "1" : "0");
writer.WriteAttributeString("minOccurs", type.IsValueType && defaultValue == null && !hasSpecifiedBoolean && !isOptional ? "1" : "0");
writer.WriteAttributeString("maxOccurs", "1");
if (defaultValue != null)
{
Expand All @@ -1189,7 +1191,7 @@ private void AddSchemaType(XmlDictionaryWriter writer, TypeToBuild toBuild, stri
writer.WriteAttributeString("type", $"{_xmlNamespaceLookup.LookupPrefix(xsTypename.Namespace)}:{xsTypename.Name}");
}

if (isAttribute && typeInfo.IsValueType && !isOptionalAttribute)
if (isAttribute && typeInfo.IsValueType && !isOptional)
{
writer.WriteAttributeString("use", "required");
}
Expand Down
Loading