I’ve been working with a lot of external systems lately that have their own objects that they serialize into either JSON or XML, and have found some good to tools to rebuild those objects into C# classes that i can add to my apps.
For XML I’ve found this one (http://xmltocsharp.azurewebsites.net/)
Some Example XML from one of the Apps I’ve been working with (This was a sample on their website)
<reply> <contents>...</contents> <attachment filename="..." md5="..."> <!-- base-64 encoded file contents --> </attachment> </reply>
The tools nicely converts to the below C#
[XmlRoot(ElementName="attachment")] public class Attachment { [XmlAttribute(AttributeName="filename")] public string Filename { get; set; } [XmlAttribute(AttributeName="md5")] public string Md5 { get; set; } } [XmlRoot(ElementName="reply")] public class Reply { [XmlElement(ElementName="contents")] public string Contents { get; set; } [XmlElement(ElementName="attachment")] public Attachment Attachment { get; set; } }
Then i can use the following code to deserialise their Response Stream from the HTTP response
Reply reply=new Reply (); var resp = CallA MethodThatReturnsaStreamResposne(); using (var sr = new StreamReader(resp)) { var xs = new XmlSerializer(reply.GetType()); reply= (Model.Tickets)(xs.Deserialize(sr)); }
Pretty similar with JSON too, using this site (http://json2csharp.com/)
However they don’t support invalid names, so i am going to use one int his example and how to work around it.
{".Name":"Jon Smith"}
public class RootObject { public string __invalid_name__.Name { get; set; } }
JSON properties support dashes and periods, which are not supported in C#, so in C# there is support for a attribute “jsonproperty” that you can use like the below to fix the issue.
public class RootObject { [JsonProperty(".Name")] public string Name { get; set; } }
Then to deserialize I use the Newtonsoft JSON libraries example below
var del = message.GetBody<string>(); var myObject = JsonConvert.DeserializeObject<RootObject>(del);
Obviously thought you would not leave it named as “RootObject” though 🙂
In the example above i was reading a JSON object from a Azure Service Bus Queue.
Lastly, thought i would add in the class i use for going back to XML. In this case i was working on today I was going to a PHP based system Kayako and it has some strange requirements.
I created a class to inherit my XML objects from so add an extension method.
public class XmlDataType { public string ToXmlString() { StringBuilder sb = new StringBuilder(); string retval = null; using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() {Encoding = Encoding.UTF8}))//{OmitXmlDeclaration = true} { var ns = new XmlSerializerNamespaces(); ns.Add("", ""); new XmlSerializer(this.GetType(),new XmlAttributeOverrides() { }).Serialize(writer, this,ns); retval = sb.ToString(); } return retval.Replace("utf-16","UTF-8"); } }
Kayako only accepts UTF8 not UTF16, adn you need to remove the xmlns properties, which i do with the Namespace declaration above.
The way I’ve changed UTF16 to 8 is a bit dodgy but it works for Kayako.
Now i can just call MyObject.ToXmlString() and get a string for the XML data that i can pass into a HTTP Request.
Noting that some of the Kayako methods don’t like the xml tag at the start, so if you need to remove this I’ve left in a bit of commented out code that you can use in the XML Writer settings initialization.
https://jsonutils.com/
This one is better for create c# class from json, it supports JsonProperty attribute
LikeLike