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
Expand Up @@ -1230,9 +1230,10 @@ protected void AddWriteCallback(Type type, string typeName, string? typeNs, XmlS
}

[RequiresUnreferencedCode("calls GetArrayElementType")]
private void WriteArray(string name, string? ns, object o, Type type)
private (string arrayTypeName, string? arrayTypeNs, Type elementType) GetArrayTypes(Type type)
{
Type elementType = TypeScope.GetArrayElementType(type, null)!;

string typeName;
string? typeNs;

Expand Down Expand Up @@ -1299,6 +1300,14 @@ private void WriteArray(string name, string? ns, object o, Type type)
if (arrayDims.Length > 0)
typeName += arrayDims.ToString();

return new(typeName, typeNs, elementType);
}

[RequiresUnreferencedCode("calls GetArrayElementType")]
private void WriteArray(string name, string? ns, object o, Type type)
{
(string typeName, string? typeNs, Type elementType) = GetArrayTypes(type);

if (_soap12 && name != null && name.Length > 0)
WriteStartElement(name, ns, null, false);
else
Expand Down Expand Up @@ -1391,8 +1400,20 @@ protected void WritePotentiallyReferencingElement(string? n, string? ns, object?
{
if (n == null)
{
TypeEntry entry = GetTypeEntry(t)!;
WriteReferencingElement(entry.typeName!, entry.typeNs, o, isNullable);
TypeEntry? entry = GetTypeEntry(t);
if (entry != null)
{
WriteReferencingElement(entry.typeName!, entry.typeNs, o, isNullable);
}
else
{
// The type was never imported (e.g. an array instance passed as an
// extra entry of a doc/bare members mapping). Unregistered arrays are
// written inline as soap Array elements (WriteArray), so reference
// them with the same element name; anything else falls back to the
// soap ur-type.
WriteReferencingElement(t.IsArray ? Soap.Array : Soap.UrType, Soap.Encoding, o, isNullable);
}
}
else
WriteReferencingElement(n, ns, o, isNullable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3536,6 +3536,36 @@ public static void XmlMembersMapping_Soap_SoapComplexTypeWithArray()
Assert.True(requestBodyValue.StringList.SequenceEqual(requestBodyActual.StringList));
}

[Fact]
public static void XmlMembersMapping_Soap_DocBare_ExtraReferencedUnregisteredMember()
{
// SOAP-encoded doc/bare members mapping (hasWrapperElement: false, writeAccessors: false).
// The object[] passed to Serialize has more entries than there are mapped members, so the
// extra entries go through the "doc/bare case

string ns = s_defaultNs;
string memberName = "DocBareMember";

XmlReflectionMember member = GetReflectionMember<string>(memberName, ns);
member.SoapAttributes.SoapElement = new SoapElementAttribute(memberName);
var members = new XmlReflectionMember[] { member };

var importer = new SoapReflectionImporter(null, ns);
var membersMapping = importer.ImportMembersMapping(elementName: null, ns, members,
hasWrapperElement: false, writeAccessors: false);
var serializer = XmlSerializer.FromMappings(new XmlMapping[] { membersMapping })[0];

var extra = new string[] { "extra" };
object[] value = new object[] { "hello", extra, extra };

string baseline = "<root><string xmlns=\"http://www.w3.org/2001/XMLSchema\" xmlns:q2=\"http://www.w3.org/2001/XMLSchema-instance\" q2:type=\"string\">hello</string><q3:Array xmlns:q3=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:q4=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:q5=\"http://www.w3.org/2001/XMLSchema\" id=\"id1\" q3:arrayType=\"q5:string[1]\"><Item>extra</Item></q3:Array><q6:Array xmlns:q6=\"http://schemas.xmlsoap.org/soap/encoding/\" href=\"#id1\"></q6:Array></root>";

object[] actual = SerializeAndDeserializeWithWrapper(value, serializer, baseline);
Assert.NotNull(actual);
Assert.Equal(1, actual.Length);
Assert.Equal("hello", (string)actual[0]);
}

[Fact]
public static void Xml_XmlTextAttributeTest()
{
Expand Down
Loading