-3

I got a class which represents a soccerplayer:

public class PlayerExtended
{
    [XmlAttribute("id")] public string Id { get; set; }
    [XmlAttribute("shortName")] public string ShortName { get; set; }
    [XmlAttribute("firstName")] public string FirstName { get; set; }
    [XmlAttribute("surName")] public string SurName { get; set; }
    [XmlAttribute("shirtNumber")] public string ShirtNumber { get; set; }
    [XmlAttribute("actions")] public string Actions { get; set; }
    [XmlAttribute("substitude")] public string Substitude { get; set; }
    [XmlAttribute("grade")] public string Grade { get; set; }
    [XmlAttribute("iconSmall")] public string IconSmall { get; set; }
    [XmlAttribute("position")] public string Position { get; set; }
    [XmlAttribute("squadPositionID")] public string SquadPositionId { get; set; }
    [XmlAttribute("squadPosition")] public string SquadPosition { get; set; }
    [XmlAttribute("inMinute")] public string InMinute { get; set; }
    [XmlAttribute("outMinute")] public string OutMinute { get; set; }
    [XmlAttribute("captain")] public string Captain { get; set; }
}

After assigning values to the properties one of the players looks like this:

playerModel The property "Actions" is an empty string (NOT NULL).

If I serialize it it looks like this:

<player id="51641" shortName="Bürki" firstName="Roman" surName="Bürki" shirtNumber="1" substitude="starter" grade="2,5" iconSmall="xxx.whatever.com" position="11" squadPositionID="1" squadPosition="Torwart"/>

But I want it to look like this:

<player id="51641" shortName="Bürki" firstName="Roman" surName="Bürki" shirtNumber="1" actions="" substitude="starter" grade="2,5" iconSmall="xxx.whatever.com" position="11" squadPositionID="1" squadPosition="Torwart"/>

So how do I serialize an XmlAttribute which is an empty string?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
k.troy2012
  • 344
  • 4
  • 21
  • Did you already try putting `[System.Xml.Serialization.XmlElement(IsNullable = true)]` attribute instead of XmlAttribute ? Did it work ? – Manoj Choudhari Feb 06 '20 at 16:01
  • Yes it "works" .. but it looks like this: – k.troy2012 Feb 06 '20 at 16:05
  • not what I want – k.troy2012 Feb 06 '20 at 16:05
  • 1
    @ManojChoudhari XmlElement is not the same as an XmlAttribute, this won't work – Timmeh Feb 06 '20 at 16:05
  • Does this answer your question? [Serialize string property as attribute, even if string is empty](https://stackoverflow.com/questions/5835102/serialize-string-property-as-attribute-even-if-string-is-empty) – Manoj Choudhari Feb 06 '20 at 16:09
  • 1
    Can't reproduce. Given `var player = new PlayerExtended { Id = "51641", Actions = "", };` the XML I am getting is ``. See: https://dotnetfiddle.net/mfWs4i Can you [edit] your question to include a [mcve] showing how you generated the XML? – dbc Feb 06 '20 at 16:09
  • @ManojChoudhari - OP states that *"Actions" is an empty string (NOT NULL)* so I don't think it is a duplicate. – dbc Feb 06 '20 at 16:12
  • Can't reproduce on .NET Core 3.1.0 https://dotnetfiddle.net/mfWs4i or .NET Framework 4.7 https://dotnetfiddle.net/2WRvvP – dbc Feb 06 '20 at 16:37

3 Answers3

1

How are you generating your XML? I cannot seem to reproduce your issue.

    public class Program
    {
        public static void Main(string[] args)
        {
            using var writer = new StringWriter();
            var serializer = new XmlSerializer(typeof(Player));
            serializer.Serialize(writer, new Player { Name = "", Age = 25 });
            Console.WriteLine(writer);
        }
    }

    public class Player
    {
        [XmlAttribute("name")]
        public string Name { get; set; }


        [XmlAttribute("age")]
        public int Age { get; set; }
    }

The code above results in the name attribute in the format you desire (name=""). Let me know if this answer is sufficient for you.

Timmeh
  • 398
  • 2
  • 14
1
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;

// Runtime Target = .NET Core v2.1 or .NET Core v3.1

namespace XmlSerialize
{
    class Program
    {
        static void Main(string[] args)
        {
            var mickey = new Employee { FirstName = "Mickey", LastName = "Mouse" };
            var asterix = new Employee { FirstName = "Asterix", LastName = "" };
            var obelix = new Employee { FirstName = "Obelix", LastName = null };
            var nixnix = new Employee { FirstName = null, LastName = null };

            Console.WriteLine(SerializeXml(mickey) + SerializeXml(asterix) + SerializeXml(obelix) + SerializeXml(nixnix));
        }

        public static string SerializeXml<T>(T instanceToSerialize)
        {
            var serializer = new XmlSerializer(instanceToSerialize.GetType(), string.Empty);
            var result = string.Empty;
            using (var stringWriter = new StringWriter())
            {
                serializer.Serialize(stringWriter, instanceToSerialize);
                result = stringWriter.ToString();
            }
            return result;
        }
    }

    [XmlRoot("Employee")]
    public sealed class Employee
    {
        [XmlAttribute("FirstName")]
        public string FirstName { get; set; }

        [XmlIgnore]
        public string LastName { get; set; }

        [XmlAttribute("LastName")]
        public string SerializableLastName // <------------ Might this help?
        {
            get { return this.LastName ?? string.Empty; }
            set { this.LastName = value; }
        }

        [XmlElement]
        public List<string> Skills { get; set; }
    }
}

Output

<?xml version="1.0" encoding="utf-16"?>
<Employee FirstName="Mickey" LastName="Mouse" />
<Employee FirstName="Asterix" LastName="" />
<Employee FirstName="Obelix" LastName="" />
<Employee LastName="" />
0

setting the property value to string.Empty will do the trick. I am using XmlSerializer to convert the object to XML. If I set the property to string.Empty, this will result as empty attribute in XML. Here is the example

public class TestClass
{
    [XmlAttribute("test1")]
    public string test1 { get; set; }
    [XmlAttribute("test2")]
    public string test2 { get; set; }
}

var dd = new List<TestClass>();

dd.Add( new TestClass() { test1 = "asdf", test2 = string.Empty }); //will generate empty attribute for test2
dd.Add( new TestClass() { test1 = "asdf" }); //the attribute test2 will be ignored

using (var stringwriter = new System.IO.StringWriter())
{
   var serializer = new XmlSerializer(dd.GetType());

   serializer.Serialize(stringwriter, dd);
   Console.WriteLine( stringwriter.ToString());
}

Output

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfTestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <TestClass test1="asdf" test2="" />
 <TestClass test1="asdf" />
</ArrayOfTestClass>
Krishna Varma
  • 4,238
  • 2
  • 10
  • 25