Search code examples
asp.netasp.net-mvc-3entity-framework-4.3intuit-partner-platform

XML File Model Mapping asp.net MVC3 ( Dynamically Map an xml file to a model class asp.net mvc3 )


I am trying to implement a payment gateway(INTUIT payment gateway). I would like to serialize an xml to an model class and save into my database. I am using Desktop Model for intuit payment gateway, as the hosted model is a pain to get working with especially ssl certificates, so i dont want to try that.

I must mention i am able to get the response using the below mentioned code, where i am stuck at the moment is serialize the xml and save the response into the database. This xml is pulled from a folder in my xmlfiles folder located in my project.

For sample xml format, check out this one. https://ipp.developer.intuit.com/0085_QuickBooks_Windows_SDK/qbms/0060_Documentation/Sending_Requests

this is an xml file i am trying to post to url (https://merchantaccount.ptc.quickbooks.com/j/AppGateway)

<?xml version="1.0"?>
<?qbmsxml version="4.5"?>
<QBMSXML>
    <SignonMsgsRq>
        <SignonDesktopRq>
            <ClientDateTime>2012-07-25T17:13:45</ClientDateTime>
            <ApplicationLogin>abc.abc.us</ApplicationLogin>
            <ConnectionTicket>TGT-1-g42FGaMfOTQ82GcWFBpsuQ</ConnectionTicket>
        </SignonDesktopRq>
    </SignonMsgsRq>
    <QBMSXMLMsgsRq>
        <CustomerCreditCardChargeRq>
            <TransRequestID>4540453787200</TransRequestID>
            <CreditCardNumber>4111111111111111</CreditCardNumber>
            <ExpirationMonth>12</ExpirationMonth>
            <ExpirationYear>2016</ExpirationYear>
            <IsCardPresent>false</IsCardPresent>
            <Amount>10.00</Amount>
        </CustomerCreditCardChargeRq>
    </QBMSXMLMsgsRq>
</QBMSXML>

The Controller i use to make a post to the url

public ActionResult Index()
{
    WebRequest req = null;
    WebResponse rsp = null;
    string fileName = Server.MapPath("~/XMLData/XMLFile1.xml");
    string uri = "https://merchantaccount.ptc.quickbooks.com/j/AppGateway";
    req = WebRequest.Create(uri);
    //req.Proxy = WebProxy.GetDefaultProxy(); // Enable if using proxy
    req.Method = "POST";        // Post method
    req.ContentType = "application/x-qbmsxml";     // content type

    // Wrap the request stream with a text-based writer
    StreamWriter writer = new StreamWriter(req.GetRequestStream());
    // Write the XML text into the stream
    writer.WriteLine(this.GetTextFromXMLFile(fileName));
    writer.Close();
    // Send the data to the webserver
    rsp = req.GetResponse();
   // var resp = (Object)rsp.GetResponseStream();
    if (rsp != null)
    {
        StreamReader inStream = new StreamReader(rsp.GetResponseStream());
        var data = inStream.ReadToEnd();

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(data);
        string path = Server.MapPath("~/XMLData/SampleXmlE2E.xml");
        xmlDoc.Save(path);//regenerates the xml file in different system.
    }

    return View();
    //XElement root = new XElement("root");
    //root.Add(new XElement("element1"));
    //root.Add(new XElement("element2"));
    //root.Add(new XAttribute("attribute1", "a value"));
    //return new XmlResult(root);
}

private string GetTextFromXMLFile(string file)
{
    StreamReader reader = new StreamReader(file);
    string ret = reader.ReadToEnd();
    reader.Close();
    return ret;
}

private string SendRequest(Uri UriObj, string data)
{
    string _result;

    var request = (HttpWebRequest)WebRequest.Create(UriObj);
    request.Method = "POST";
    request.ContentType = "text/xml";
    var writer = new StreamWriter(request.GetRequestStream());
    writer.Write(data);
    writer.Close();

    var response = (HttpWebResponse)request.GetResponse();

    var streamResponse = response.GetResponseStream();
    var streamRead = new StreamReader(streamResponse);

    _result = streamRead.ReadToEnd().Trim();
    streamRead.Close();
    streamResponse.Close();
    response.Close();
    return _result;
}

Any help would be appreciated. Thanks


Solution

  • Varun,

    [Edit -update]

    Based on this XML:

    <?qbmsxml version="4.5"?>
    <QBMSXML>
      <SignonMsgsRq>
        <SignonDesktopRq>
          <ClientDateTime>2012-07-25T17:13:45</ClientDateTime>
          <ApplicationLogin>app.app.login.url</ApplicationLogin>
          <ConnectionTicket>TGT-1-g42FGaMfOTQ82GcWFBpsuQ</ConnectionTicket>
        </SignonDesktopRq>
      </SignonMsgsRq>
      <QBMSXMLMsgsRq>
        <CustomerCreditCardChargeRq>
          <TransRequestID>4540453787200</TransRequestID>
          <CreditCardNumber>4111111111111111</CreditCardNumber>
          <ExpirationMonth>12</ExpirationMonth>
          <ExpirationYear>2016</ExpirationYear>
          <IsCardPresent>false</IsCardPresent>
          <Amount>10.00</Amount>
        </CustomerCreditCardChargeRq>
      </QBMSXMLMsgsRq>
    </QBMSXML>
    

    Here's the class structure that you'd need to deserialize into as per the example above:

    [XmlRoot("QBMSXML")]
    public class QbmsXml
    {
        [XmlElement("SignonMsgsRq")]
        public SignonMsgsRq SignonMsgsRq { get; set; }
    
        [XmlElement("QBMSXMLMsgsRq")]
        public QbmsXmlMsgsRq QbmsXmlMsgsRq { get; set; }
    }
    
    public class SignonMsgsRq
    {
        [XmlElement("SignonDesktopRq")]
        public SignonDesktopRq SignonDesktopRq { get; set; }
    }
    
    public class SignonDesktopRq
    {
        [XmlElement("ClientDateTime")]
        public DateTime ClientDateTime { get; set; }
    
        [XmlElement("ApplicationLogin")]
        public string ApplicationLogin { get; set; }
    
        [XmlElement("ConnectionTicket")]
        public string ConnectionTicket { get; set; }
    }
    
    public class QbmsXmlMsgsRq
    {
        [XmlElement("CustomerCreditCardChargeRq")]
        public CustomerCreditCardChargeRq CustomerCreditCardChargeRq { get; set; }
    }
    
    public class CustomerCreditCardChargeRq
    {
        [XmlElement("TransRequestID")]
        public Int64 TransRequestID { get; set; }
    
        [XmlElement("CreditCardNumber")]
        public string CreditCardNumber { get; set; }
    
        [XmlElement("ExpirationMonth")]
        public int ExpirationMonth { get; set; }
    
        [XmlElement("ExpirationYear")]
        public int ExpirationYear { get; set; }
    
        [XmlElement("IsCardPresent")]
        public bool IsCardPresent { get; set; }
    
        [XmlElement("Amount")]
        public double Amount { get; set; }
    }
    

    Just use the xmlSerialiser along the lines of:

    class Program
    {
        private static T DeSerialize<T>(string fromXmlFile) where T: class
        {
            if (!File.Exists(fromXmlFile))
            {
                return default(T);
            }
            T deserializedClass;
            var serializer = new XmlSerializer(typeof(T));
    
            // ToDo: add error catching etc
            using (var reader = new StreamReader(fromXmlFile))
            {
                deserializedClass = (T)serializer.Deserialize(reader);
            }
            return deserializedClass;
        }
    
        static void Main(string[] args)
        {
            var yourXmlFilePath = @"d:\temp\xmltest.xml";
            var deserializedClass = DeSerialize<QbmsXml>(yourXmlFilePath);
    
            Console.WriteLine(deserializedClass
                                .QbmsXmlMsgsRq
                                .CustomerCreditCardChargeRq.Amount);
            Console.Read();
        }
    }
    

    hope this helps.