c#.Net dynamically call Navision 2009 SP1 Web Service Issues

MartinaLMartinaL Member Posts: 3
edited 2011-11-14 in NAV Three Tier
I currently have a codeunit setup in Navision that excepts and XMLPort parameter of contacts as a web service.

I am using this web service in a c# .Net application which is run from SQL Server Service Broker.

Because of the Service Broker on the .Net side, i need to be able to call the NAV Web Service dynamically and handle failures etc by saving the web service request in a database table to be retried.

The issue i am having is that I can create an object in my c# code which maps to the xmlPort expected by Navision and then i send this as a sting into the Service Request for the web service call to UpdateContacts.

If i call the UpdateContacts method directly by consuming the Navision web service and sending in a contacts object it works fine, but when i try and do this using Service Broker to handle errors etc I get the error message;
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">
a:Microsoft.Dynamics.Nav.Service.WebServices.ServiceBrokerException</faultcode><faultstring xml:lang="en-AU">Parameter contactXML in method 
UpdateContacts in service ExampleService is null! </faultstring><detail><string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
Parameter contactXML in method UpdateContacts in service ExampleService is null! </string></detail></s:Fault></s:Body></s:Envelope>

This is the code that is building up the service request which ultimately fails with the above message, but if i call --- it works fine! (but i can't do it this way because i need Service Broker to handle pendign and failed requests etc;
private ExampleService m_webservice = new ExampleService();

m_webservice.Credentials = new NetworkCredential("Username", "Password", "Domain");

                List<contact> _list = new List<contact>();

                var xDocument = XDocument.Parse(s_msgReceived.BodyAsString);
                var result = from e in xDocument.Descendants("bvc_User") // this is from the Service Broker message queue
                             select e;

                foreach (var item in result)
                {
                    contact _contact = new contact { no = "ContactNumber", name = item.Attribute("FirstName").Value, address = "Test 1", address2 = "Test 2" };
                    _list.Add(_contact);
                }

                contacts _contacts = new contacts();
                _contacts.contact = (contact[])_list.ToArray();

                var objectDocument = new XmlDocument();
                using (XmlWriter writer = (objectDocument.CreateNavigator()).AppendChild())
                {
                    (new XmlSerializer(_contacts.GetType())).Serialize(writer, _contacts);
                    writer.Close();
                }

                XDocument xd = XDocument.Load(new XmlNodeReader(objectDocument));

                m_webservice.UpdateContacts(_contacts); // this works fine but i can't ultimately do it this way due to the SQL Service Broker requirements

                // Build up the Soap web service envelope
                string requestString = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
                requestString += "<soap:Body>";
                requestString += "<UpdateContacts xmlns=\"urn:microsoft-dynamics-schemas/codeunit/ExampleService\" >";
                requestString += "<![CDATA[";
                requestString += xd;
                requestString += "]]>";
                requestString += "</UpdateContacts>";
                requestString += "</soap:Body>";
                requestString += "</soap:Envelope>";

                // Build up the HttpRequest that will hold our Soap message
                r = new httpRequestType();
                r.url = m_webservice.Url;
                r.protocolVersion = "HTTP/1.1";
                r.method = "POST";
                r.headers = new headerType[2];
                r.headers[0] = new headerType();
                r.headers[0].name = "SOAPAction";
                r.headers[0].value = "urn:microsoft-dynamics-schemas/codeunit/ExampleService:UpdateContacts";
                r.headers[1] = new headerType();
                r.headers[1].name = "Content-Type";
                r.headers[1].value = "text/xml; charset=utf-8";
                r.body = new ASCIIEncoding().GetBytes(requestString);

                ServiceRequest(r);

Service Request goes onto create a HTTPWebRequest and attempt to send it etc

xd as XML looks like;
<contacts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <contact xmlns="urn:microsoft-dynamics-nav/xmlports/x50012">
    <no>70191844</no>
    <name>Thomas</name>
    <address>Test 1</address>
    <address2>Test 2</address2>
  </contact>
</contacts>

This is what the codeunit currently looks like in NAV;
OBJECT Codeunit 50069 WebServiceExample
{
  OBJECT-PROPERTIES
  {
    Date=09/05/11;
    Time=[ 5:17:34 PM];
    Modified=Yes;
  }
  PROPERTIES
  {
    OnRun=BEGIN
          END;

  }
  CODE
  {

    PROCEDURE UpdateContacts@1101234001(ContactXML@1101234000 : XMLport 50012);
    BEGIN
      ContactXML.IMPORT;
      ContactXML.UpdateContacts();
    END;

    PROCEDURE GetContact@1101240000(ContactNo@1101234002 : Code[20];VAR ContactXML@1101240000 : XMLport 50012) sReturn : Text[1024];
    VAR
      contacts@1101234000 : Record 5050;
    BEGIN

      ContactXML.GetContacts(ContactNo);
    END;

    PROCEDURE GetALLContacts@1101234000(VAR ContactXML@1101234000 : XMLport 50012);
    BEGIN
      ContactXML.GetAllContacts;
    END;

    BEGIN
    END.
  }
}

Comments

Sign In or Register to comment.