views:

12

answers:

0

I am working on integrating an application in to Zendesk (zendesk.com). My problem is that their webservice accepts JSON or POX. So i have a class "Ticket" and "TicketField" that look like this:

[XmlRoot(Namespace = "", ElementName = "ticket-field-entry")]
public class TicketField : IXmlSerializable
{
    public int Id;

    public string Value;

    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {

    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("ticket-field-id", Id.ToString());
        writer.WriteElementString("value", Value);
    }

    #endregion
}
[XmlRoot(Namespace = "", ElementName = "ticket")]
public class Ticket : IXmlSerializable
{
    public int Priority;

    public int Type;

    public List<TicketField> TicketFields;

    public string Description;

    public string RequestName;

    public string Email;

    public string Subject;


    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {

    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("priority-id", Priority.ToString());
        writer.WriteElementString("type", Type.ToString());
        writer.WriteStartElement("ticket-field-entries");
        writer.WriteAttributeString("type","array");
        TicketFields.ForEach(ticket =>
                             {
                                 writer.WriteStartElement("ticket-field-entry");
                                 ticket.WriteXml(writer);
                                 writer.WriteEndElement();
                             });
        writer.WriteEndElement();

        writer.WriteElementString("description", Description);
        writer.WriteElementString("requester-name", RequestName);
        writer.WriteElementString("requester-email", Email);
        writer.WriteElementString("subject", Subject);
    }

    #endregion
}

and to serialize an the object to a string I call:

public static string SerializeToString(object obj)
    {
        DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
        using (var backing = new StringWriterUtf8())
       {
           using(var writer = new XmlTextWriter(backing))
           {
               serializer.WriteObject(writer, obj);
               return backing.ToString();
           }
       }
    }

public class StringWriterUtf8: StringWriter
{
    public override Encoding Encoding
    {
        get
        {
            return Encoding.UTF8;
        }
    }
}

Now my problem is deserializing any response i get back (an HttpWebResponse with an XML body).

Ive looked at the XmlReader, and it seems to be quite cumbersome to navigate, especially if elements are in no particular order, or are missing. So I thought i would use an XPathNavigor and use it for something like:

public void ReadXml(XmlReader reader)
    {
        XPathDocument xp = new XPathDocument(reader);

        var navigator = xp.CreateNavigator();
        navigator.MoveToFirstChild();
        Priority = int.Parse(navigator.SelectSingleNode("priority-id").InnerXml);
        Description = navigator.SelectSingleNode("description").InnerXml;


    }

Is there a better way or am i missing something? Also, the reason i inherit from IXmlSerializable is because both the XmlSerializer and the DataContractSerializer put an attribute ("xmlns:i") in the root node by default, and the webservice is not able to understand the attribute and throws an error.

This is a C# .NET 3.5 project.