1

I am defining new contract for my WEB API where I want to have specific XML formatting so it can accept the XML below, which I want to parse into my classes classes below. The JSON format maps exactly how I expected, but XML is not.

How do I stop generating "Members" wrapper node in XML?

The XML I want to parse into classes:

<MembersUpdate>
<NotificationUrl>http://yoururl/member/profile/</NotificationUrl>
<Timestamp >2017-04-11T12:13:35.6516915Z</Timestamp>
<Member>
    <MemberId>0</MemberId>
    <LastUpdated>0001-01-01T00:00:00</LastUpdated>
</Member>
<Member>
    <MemberId>0</MemberId>
    <LastUpdated>0001-01-01T00:00:00</LastUpdated>
</Member>
<Member>
    <MemberId>0</MemberId>
    <LastUpdated>0001-01-01T00:00:00</LastUpdated>
</Member>
<Member>
    <MemberId>0</MemberId>
    <LastUpdated>0001-01-01T00:00:00</LastUpdated>
</Member>
</MembersUpdate>

Mapping classes:

    /// <remarks/>
[DataContract]
public partial class MembersUpdate
{
    /// <remarks/>
    [DataMember]
    public string NotificationUrl { get; set; }

    /// <remarks/>
    [DataMember]
    public System.DateTime Timestamp { get; set; }

    /// <remarks/>
    [DataMember]
    public MembersUpdateMember[] Member { get; set; }
}

/// <remarks/>
[DataContract]
public partial class MembersUpdateMember
{
    /// <remarks/>
    [DataMember]
    public byte MemberId { get; set; }

    /// <remarks/>
    [DataMember]
    public System.DateTime LastUpdated { get; set; }
}

However the example rendered does have additional node, and my original XML cannot be parsed. I have added sample rendered for the structure below:

<MembersUpdate xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/CivicaSystemsLtd.Areas.Notices.ApiControllers">
      <Member>
        <MembersUpdateMember>
          <LastUpdated>2017-04-11T23:58:06.6310087+01:00</LastUpdated>
          <MemberId>64</MemberId>
        </MembersUpdateMember>
        <MembersUpdateMember>
          <LastUpdated>2017-04-11T23:58:06.6310087+01:00</LastUpdated>
          <MemberId>64</MemberId>
        </MembersUpdateMember>
      </Member>
      <NotificationUrl>sample string 1</NotificationUrl>
      <Timestamp>2017-04-11T23:58:06.6300095+01:00</Timestamp>
    </MembersUpdate>
cpoDesign
  • 8,953
  • 13
  • 62
  • 106

1 Answers1

0

This is nearly impossible, since the WebAPI uses the DataContractSerializer.

If you can switch to the XmlSerializer, you could do the following:

[XmlElement(ElementName = "Member")]
public MembersUpdateMember[] Member { get; set; }

You could switch on demand via an attribute on your Controller:

public class UseXmlSerializerAttribute : Attribute, IControllerConfiguration
{
    public void Initialize(HttpControllerSettings controllerSettings,
                           HttpControllerDescriptor controllerDescriptor)
    {
        var xmlFormater = new XmlMediaTypeFormatter {UseXmlSerializer = true};

        controllerSettings.Formatters.Clear();
        controllerSettings.Formatters.Add(xmlFormater);
    }
}

Then use it on your controller:

[UseXmlSerializer]
public class FooController : ApiController
{
}
Community
  • 1
  • 1
Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111