Serialize XmlAttribute which is an empty string [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
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:
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?

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.

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="" />

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>

Related

XML Deserialize to class

I am trying to deserialize an XDocument to a class. I am calling USPS the CityStateLookupResponse API. Every time I deserialize to my class object, the object is always null.
Here is my class
[Serializable()]
[XmlRoot("CityStateLookupResponse", IsNullable = false)]
public class CityStateLookUpResponse
{
[XmlAttribute("ID")]
public string Id { get; set; }
[XmlElement("City")]
public string City { get; set; }
[XmlElement("State")]
public string State { get; set; }
[XmlElement("Zip5")]
public string Zip { get; set; }
}
Below is the code I use to call USPS
XDocument requestDoc = new XDocument(
new XElement("CityStateLookupRequest",
new XAttribute("USERID", _postOfficeOptions.UserId),
new XElement("Revision", "1"),
new XElement("ZipCode",
new XAttribute("ID", "0"),
new XElement("Zip5", zipCode.ToString())
)
)
);
try
{
var url = _postOfficeOptions.Url + requestDoc;
var client = new WebClient();
var response = client.DownloadString(url);
var xdoc = XDocument.Parse(response.ToString());
XmlSerializer serializer = new XmlSerializer(typeof(CityStateLookUpResponse));
if (!xdoc.Descendants("ZipCode").Any()) return null;
return (CityStateLookUpResponse)serializer.Deserialize(xdoc.CreateReader());
}
catch (Exception ex)
{
throw new Exception("In CityStateLookUp:", ex);
}
This line of code always returns null
return (CityStateLookUpResponse)serializer.Deserialize(xdoc.CreateReader());
This is a valid response from the USPS API
<?xml version="1.0"?>
<CityStateLookupResponse><ZipCode ID="0"><Zip5>90210</Zip5>
<City>BEVERLY HILLS</City><State>CA</State></ZipCode>
</CityStateLookupResponse>
Any help would be appreciated
The problem is that you are trying to deserialize starting at the wrong node. The root node for your response is CityStateLookupResponse. That contains a list of ZipCode nodes, and it is the ZipCode nodes that correspond to your current CityStateLookUpResponse class.
You can fix this by changing your response class like this:
[Serializable()]
[XmlRoot("CityStateLookupResponse", IsNullable = false)]
public class CityStateLookupResponse
{
[XmlElement("ZipCode")]
public List<ZipCode> ZipCode { get; } = new();
}
[Serializable()]
[XmlRoot("ZipCode", IsNullable = false)]
public class ZipCode
{
[XmlAttribute("ID")]
public string Id { get; set; }
[XmlElement("City")]
public string City { get; set; }
[XmlElement("State")]
public string State { get; set; }
[XmlElement("Zip5")]
public string Zip { get; set; }
}

XmlSerlializer is not serializing all properties of a class

I wrote a generic method for Object to XML string using XMLSerializer class.
Below is my class
public class SampleJson
{
public string fname { get; set; }
public string lname { get; set; }
public int age { get; set; }
public AdditionalInformation AdditionalInformation { get; set; }
}
public class AdditionalInformation
{
public string firstlane { get; set; }
public string secondlane { get; set; }
public decimal? cityCode { get; set; }
public int? countryCode { get; set; }
public bool? isValid { get; set; }
public DateTime enteredDate { get; set; }
}
And below is Generic Method
public class QAZ
{
public static string Foo<T>(T dataToSerialize)
{
var stringWriter = new StringWriter();
XmlTextWriter xmlTextWriter = null;
var serializer = new XmlSerializer(dataToSerialize.GetType());
xmlTextWriter = new XmlTextWriter(stringWriter);
serializer.Serialize(xmlTextWriter, dataToSerialize);
return stringWriter.ToString();
}
}
class Bar
{
static void Main(string[] args)
{
var sampleJson = typeof(SampleJson);
var fooMethod = typeof(QAZ).GetMethod("Foo");
var fooOfBarMethod = fooMethod.MakeGenericMethod(new[] {sampleJson});
string xml= fooOfBarMethod.Invoke(new QAZ(), new object[] {new SampleJson()}).ToString();
Console.ReadKey();
}
}
But I'm getting the output is
<?xml version="1.0" encoding="UTF-16"?>
-<SampleJson xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<age>0</age>
</SampleJson>
I don't understand why XmlSerializer serializes only int property.
Can anyone please tell me the issue that I'm doing.
The main agenda here is I want to generate an xsd for SampleJson class. In order to do that I am trying to convert the class to xml. From xml to xsd. Is there a way to generate xsd from a class?
I think this might help you to understand better, I wrote an example please do like or dislike if it has or hasn't helped.
public class Vehicle
{
public string VRM;
}
class Program
{
static void Main(string[] args)
{
var Reg = new Vehicle { VRM = "LP65 UGT" };
var writer = new System.Xml.Serialization.XmlSerializer(typeof(Vehicle));
var wfile = new System.IO.StreamWriter(#"C:\Myexample\NewVehicle.xml");
writer.Serialize(wfile, Reg);
wfile.Close();
Console.WriteLine("Vehicle Reg is now written in xml format ");
Console.ReadKey();
}
}
The above example will write successfully to XML file ensure you create the folder first on your C drive My example and then run the above to see the result for yourself and see if it can point you to the correct direction hopefully.

c# Newtonsoft deserialize a json string in al list of Objects

i have the following class
using System;
public class AppEventsClass
{
public string title { get; set; }
public string description { get; set; }
}
after calling a remote webservice i retrive the following json string:
{"d":"[title\":\"test\",\"description\":\"test desc\"},{\"title\":\"test2\",\"description\":\"desc test 2\"}]"}
after retriving that json string, how can i convert the string in a List<> of AppEventsClass with Newtonsoft?
I tried several solutions, but nothing that works fine for me.
for example this:
List<AppEventsClass> result = new List<AppEventsClass>();
result = JsonConvert.DeserializeObject<List<AppEventsClass>>(content).ToList();
and this is the .asmx that serializes the string:
[ScriptMethod(UseHttpGet = true)]
public string GetEvents()
{
using (mySQLDataContext ctx = new secondosensoSQLDataContext())
{
List<eventi> eventiList = ctx.eventi.ToList();
List<AppEventsClass> eventiClassList = new List<AppEventsClass>();
for (int i = 0; i < eventiList.Count; i++)
{
AppEventsClass a = new AppEventsClass();
a.title = eventiList[i].titlolo_evento;
a.description = eventiList[i].descrizione_evento;
eventiClassList.Add(a);
}
var json = JsonConvert.SerializeObject(eventiClassList);
return json;
}
}
1st issues seems that the response we retrieve is not formed correctly
Assumed that the json string is looking like the following:
{"d":[{"title":"test","description":"test desc"},{"title":"test2","description":"desc test 2"}]}
The correct class for deserialization should look like this
public class Rootobject
{
public D[] d { get; set; }
}
public class D
{
public string title { get; set; }
public string description { get; set; }
}
Thanks
PS. Here is a working example:
class Program
{
static void Main(string[] args)
{
string json = "{\"d\":[{title:\"test\",description:\"test desc\"},{title:\"test2\",description:\"desc test 2\"}]}";
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(json);
}
}
public class Rootobject
{
public D[] d { get; set; }
}
public class D
{
public string title { get; set; }
public string description { get; set; }
}

XML to custom Object

I have one xml file and I want to generate custom list from that xml using Linq.
here is my code. But I am not getting any records.Here is my code.
public class TemplateSettings {
public string DecimalSeparator { get; set; }
public string ThousandSeparator { get; set; }
public string DateSeparator { get; set; }
public string TimeSeparator { get; set; }
}
XML Here
<TemplateSetting>
<DecimalSeparator>1</DecimalSeparator>
<ThousandSeparator>2</ThousandSeparator>
<DateSeparator>3</DateSeparator>
<TimeSeparator>4</TimeSeparator>
<DateFormat>dd/MM/yyyy</DateFormat>
<ValueDelimiter>tr</ValueDelimiter>
<QuoteCharacter>r</QuoteCharacter>
<IsHeader>False</IsHeader>
</TemplateSetting>
And my code to get object from xml is
var a = (from x in objTemplateMasterEAL.TemplatSettingsXML.Elements("TemplateSetting")
select new TemplateSettings()
{
DateFormat = (string)x.Element("DateFormat"),
DecimalSeparator = (string)x.Element("DecimalSeparator"),
ThousandSeparator = (string)x.Element("ThousandSeparator"),
DateSeparator = (string)x.Element("DateSeparator"),
TimeSeparator = (string)x.Element("TimeSeparator"),
QuoteCharacter = (string)x.Element("QuoteCharacter"),
ValueDelimiter = (string)x.Element("ValueDelimiter"),
IsHeaderLine = (bool)x.Element("IsHeader")
}).ToList<TemplateSettings>();
Can any one suggest me what is wrong here ?
If your goal is just to deserialize the XML to object you can simply use this:
class Program
{
static void Main(string[] args)
{
using (StreamReader reader = new StreamReader("Sample.xml"))
{
var serializer = new XmlSerializer(typeof(TemplateSetting));
var templateSetting = (TemplateSetting)serializer.Deserialize(reader);
}
}
}
[XmlRoot]
public class TemplateSetting
{
public string DecimalSeparator { get; set; }
public string ThousandSeparator { get; set; }
public string DateSeparator { get; set; }
public string TimeSeparator { get; set; }
}
I make only on one change and its working fine for me.
<TemplateSettings>
<TemplateSetting>
<DecimalSeparator>1</DecimalSeparator>
<ThousandSeparator>2</ThousandSeparator>
<DateSeparator>3</DateSeparator>
<TimeSeparator>4</TimeSeparator>
<DateFormat>dd/MM/yyyy</DateFormat>
<ValueDelimiter>tr</ValueDelimiter>
<QuoteCharacter>r</QuoteCharacter>
<IsHeader>False</IsHeader>
</TemplateSetting>
</TemplateSettings>

Advice on parsing XML document

Hoping to get some help on this: I am very thankful that a developer shared this XML file with me because it should save me a lot of headache. But he told me I am on my own with how to read it. Basically I am writing a windows store app for a card game. I have a XML that is my list of cards and want to read it into a list. I get no errors, and have read XML into lists before. Any advice would be appreciated.
Here is a snippet of XML:
<?xml version="1.0" encoding="UTF-8"?><carddatabase>
<cards>
<card>
<name>Tundra Kavu</name>
<set picURL="http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=26805&type=card" picURLHq="" picURLSt="">AP</set>
<color>R</color>
<manacost>2R</manacost>
<type>Creature - Kavu</type>
<pt>2/2</pt>
<tablerow>2</tablerow>
<text>{T}: Target land becomes a Plains or an Island until end of turn.</text>
</card>
</cards>
</carddatabase>
Here is my serializer:
public async void readFile()
{
StorageFolder myFolder = ApplicationData.Current.LocalFolder;
StorageFile myFile = await myFolder.CreateFileAsync("cards.xml", CreationCollisionOption.OpenIfExists);
XmlSerializer Serializer = new XmlSerializer(typeof(List<card>), new XmlRootAttribute("carddatabase"));
string XmlString = await FileIO.ReadTextAsync(myFile);
XmlDocument xmlDoc = await XmlDocument.LoadFromFileAsync(myFile);
var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Auto, IgnoreWhitespace = true, IgnoreComments = true };
var stringReader = new StringReader(XmlString);
XmlReader reader = XmlReader.Create(stringReader, settings);
List<card> temp = (List<card>)Serializer.Deserialize(reader);
foreach(card x in temp)
{
await tempTable.InsertAsync(x);
}
}
Here is my card class:
public class card
{
public string id { get; set; }
public string name { get; set; }
public string manacost { get; set; }
public string set { get; set; }
public string color { get; set; }
public string tablerow { get; set; }
public string text { get; set; }
public string type { get; set; }
}
You can parse xml with Linq:
XDocument xdoc = XDocument.Load(myFile);
var cards = from c in xdoc.Descendants("card")
select new card() {
name = (string)c.Element("name"),
manacost = (string)c.Element("manacost"),
set = (string)c.Element("set"),
color = (string)c.Element("color"),
tableRow = (string)c.Element("tablerow"),
text = (string)c.Element("text"),
type = (string)c.Element("type")
};
foreach(var card in cards)
await tempTable.InsertAsync(card);
Also Linq allows you to cast values from string to other datatypes, so you can have property int TableRow { get; set; } in your class, which could be parsed as TableRow = (int)c.Element("tablerow") (or int? if tablerow element is not required).
BTW in C# we use CamelCase names for types and properties. So, consider to have type like:
public class Card
{
public string Id { get; set; }
public string Name { get; set; }
public string ManaCost { get; set; }
public string Set { get; set; }
public string Color { get; set; }
public int TableRow { get; set; }
public string Text { get; set; }
public string Type { get; set; }
}

Categories

Resources