7

I have been asked to provide the following XML document from an http endpoint, exactly like:-

<?xml version="1.0" encoding="utf-8"?> 
  <XMLFile xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SalesOrders>
 ...
</SalesOrders>

However Web API spits out

<?xml version="1.0" encoding="utf-8"?>
<XMLFile xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://schemas.datacontract.org/2004/07/White.Label.Ordering.Infrastructure.Data.Queries.Export">
    <SalesOrders>
        ...
    </SalesOrders>

I have google around and tried various fixes but to no avail, my model looks like

[DataContract]
public class XMLFile
{
    [DataMember]
    public List<SalesOrder> SalesOrders { get; set; }
}

[DataContract]
public class SalesOrder
{
    [DataMember(Order = 1)]
    public string OrderNumber { get; set; }
}

and my set up lools like this

    public static void Register(HttpConfiguration config)
    {
        config.Formatters.XmlFormatter.WriterSettings.OmitXmlDeclaration = false;
        ...

    }

How do I remove xmlns:i and xmlns and replace with xmlns:xsd and xmlns:xsi?

I know this is a bad question as it shouldn't matter but my consuming client is barfing.

Rippo
  • 22,117
  • 14
  • 78
  • 117

1 Answers1

4

If you need your XML to look exactly like something, then you might be better off with XmlSerializer. DataContractSerializer doesn't give you the same level of control as it's rather assumed you use it on both ends.

That said, I would imagine your consuming client is 'barfing' because the two instances are semantically different. The first has an empty default namespace, and the second has a default namespace of http://schemas.datacontract.org/2004/07/White.Label.Ordering.Infrastructure.Data.Queries.Export.

This should be the only thing you need to correct, which you can do by setting the namespace of the DataContract.

[DataContract(Namespace="")]
public class XMLFile
{
    [DataMember]
    public List<SalesOrder> SalesOrders { get; set; }
}

[DataContract(Namespace="")]
public class SalesOrder
{
    [DataMember(Order = 1)]
    public string OrderNumber { get; set; }
}

This will give you:

<?xml version="1.0" encoding="utf-8"?>
<XMLFile xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <SalesOrders>
        ...
    </SalesOrders>
</XMLFile>
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Thanks, I have tried this on the XMLFile class, but did not add the Namesspace to all the underlying class namespaces. Will ask the client to try again. Thanks – Rippo Nov 02 '16 at 09:23
  • Ah crap the consuming client is still barfing. Stupid antiquated xml systems, looks like I need to go down the XMLSerializer path – Rippo Nov 02 '16 at 13:14
  • Went down the XMLSerializer instead, stupid means I can't use webapi anymore to future proof it for content type negotiation. Thanks – Rippo Nov 02 '16 at 13:45
  • Is there any way we can remove xmlns:i also from response message ? – Ranjith Murthy Apr 13 '18 at 08:59
  • @RanjithMurthy it's not something you can control. And it shouldn't matter. The only way I can think to remove it would be to parse the result again using e.g. `XDocument` and remove the attribute there. – Charles Mager Apr 13 '18 at 09:03