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