2

I am creating an ASP.NET Core Web API endpoint which will fetch XML output in the Nautix compliant XML. Despite the XmlAttribute set on the class, it does not return attribute in the output. Please suggest what I am doing wrong.

I am using this one in the controller to generate the xml output.

[Produces("application/xml")]

Method being called to get the XML:

private ActionResult GetXmlResponse()
{
    var sample = new Nautix
          {
              Xmlns = "https://nautix.nautic-network.org/v1.3/",
              Xsi = "http://www.w3.org/2001/XMLSchema-instance",
              Version = "1.3",
              Origin = "Api.Catamarans.com",
              Date = DateTime.Now,
              SchemaLocation = "https://nautix.nautic-network.org/v1.3/ https://nautix.nautic-network.org/v1.3/NautiX.xsd",
              Account = new Account
              {
                  Token = "101",
                  AccountName = "Catamarans.com"
              }
          };

    return new ContentResult
          {
              Content = sample.ToString(),
              ContentType = "application/xml",
              StatusCode = StatusCodes.Status200OK
          };
}

Sample class with XML decoration:

[XmlRoot(ElementName = "nautix")]
public class Nautix
{
    [XmlAttribute(AttributeName = "xmlns")]
    public string Xmlns { get; set; }

    [XmlAttribute(AttributeName = "xsi")]
    public string Xsi { get; set; }

    [XmlAttribute(AttributeName = "version")]
    public string Version { get; set; }

    [XmlAttribute(AttributeName = "origin")]
    public string Origin { get; set; }

    [XmlAttribute(AttributeName = "date")]
    public DateTime Date { get; set; }

    [XmlAttribute(AttributeName = "schemaLocation")]
    public string SchemaLocation { get; set; }

    [XmlElement(ElementName = "script")]
    public List<Script> Script { get; set; }

    [XmlElement(ElementName = "account")]
    public Account Account { get; set; }

    [XmlText]
    public string Text { get; set; }
}

I have tried different ways, but without success so far.

var xmlDoc = new XmlDocument();

// Create the header of the response
xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", string.Empty));

// Create the response body
var rootNode = xmlDoc.CreateElement("NautiX");
xmlDoc.AppendChild(rootNode);

rootNode.SetAttribute("xmlns", nautix.Xmlns);
rootNode.SetAttribute("xmlns:xsi", nautix.Xsi);
rootNode.SetAttribute("version", nautix.Version);
rootNode.SetAttribute("origin", nautix.Origin);
rootNode.SetAttribute("date", nautix.Date.ToString("yyyy-MM-ddTHH:mm:ssZ"));
rootNode.SetAttribute("xsi:schemaLocation", nautix.SchemaLocation);

var accountNode = xmlDoc.CreateElement("Account");
rootNode.AppendChild(accountNode);

var tokenNode = xmlDoc.CreateElement("Token");
tokenNode.InnerText = nautix.Account.Token;
accountNode.AppendChild(tokenNode);

var accountNameNode = xmlDoc.CreateElement("AccountName");
accountNameNode.InnerText = nautix.Account.AccountName;
accountNode.AppendChild(accountNameNode);

My goal is to get the output in the XML specified with XmlAttribute, XmlElement & XmlRoot being honoured as defined in the class definition.

I might be doing something wrong. I always worked with JSON output, this is the first time I'm working with XML.

I have added this code in ConfigureServices in Startup.cs:

services.AddControllers()
        .AddXmlDataContractSerializerFormatters();

A complete sample XML file is here:

https://nautix.nautic-network.org/v1.3/NautiX.xml

1 Answer 1

3
+50

Unlike many, I have no particular beef with XML. I like XML. I think it’s got a couple of things on JSON and it’s fine. But when you start dealing with namespaces and schemas, you’re getting yourself into some enterprisey territory that you wouldn’t wish on anyone. You can surely understand it all, or you can just mess around until stuff works. I opt for the latter, so here are some changes that should make your results look the way you want.

1. Use AddXmlSerializerFormatters()

This uses the older XmlSerializer from System.Xml.Serialization and will honor your class and member attributes.

builder.Services.AddControllers().AddXmlSerializerFormatters();

If you must keep using DataContractSerializer, I believe you’ll have to handle much of the serialization yourself.

2. If you want your attribs to say xsi:, give them the namespace

[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string SchemaLocation { get; set; }

3. For collections, use the XmlArray attributes

[XmlArray("phones")]
[XmlArrayItem("phone")]
public List<Phone> Phones { get; set; }
public class Phone
{
    [XmlAttribute(AttributeName = "type")]
    public string Type { get; set; }

    [XmlText]
    public string Number { get; set; }
}

4. Tell the Controller to output XML

You’re already using the Produces attribute, but then you’re constructing your own ActionResult just calling ToString() on the object. All you need to do is return the object itself and the framework will take care of the serialization.

[Produces("application/xml")]
public ActionResult GetXmlResponse()
{
    var sample = new Nautix
    { /* … */ };

    return Ok(sample);
}

I think that should be all. I omitted Script because I don’t have the class and it’s not in the linked example.

Output:

<nautix xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3"
        origin="Api.Catamarans.com"
        date="2025-11-07T10:00:00.1403438+02:00"
        xsi:schemaLocation="https://nautix.nautic-network.org/v1.3/ https://nautix.nautic-network.org/v1.3/NautiX.xsd">
    <account token="101">
        <account_name>Catamarans.com</account_name>
    </account>
</nautix>

If you must have the date without the fractional seconds, just use an additional string property and control the formatting to your liking.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much @BenderBoy AddXmlSerializerFormatters did the wonder compared to AddXmlDataContractSerializerFormatters, which was preventing it to honour the xml decoration. I am going ahead further to create the complete xml.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.