How to consume a Lawson Web Service from a Personalized Script in Smart Office

Calling Lawson Web Service (LWS) from a Personalized Script in Lawson Smart Office is very useful as LWS has three adapters: M3 API, SQL, and M3 Display Program (MDP).

As of today, there are three known solutions to call LWS from a script: 1) the “Big string”, 2) the XML writer, and 3) the C# proxy written with Microsoft Visual Studio. Each of these solutions has its advantages and disadvantages.

In the paper How to call LWS from a JScript I illustrate a new solution which complements the other three known solutions. This new solution is interesting as it minimizes code source surface while still ensuring SOAP validation. And the solution does not involve any C# coding, nor does it require Microsoft Visual Studio. For this new solution, we will use the free Microsoft Web Services Description Language Tool (wsdl.exe) to generate a proxy class in C# that we’ll use from JScript.NET.

As an addendum to the paper, I write two additions. First, it’s possible to make the C# proxy re-usable for multiple environments (ex: DEV, PRD, TST) by setting the variable Url of the proxy instance. Second, I have successfully tested this technique with all three LWS adapters: M3 API, SQL, and MDP.

Related articles

Published by

thibaudatwork

ex- M3 Technical Consultant

20 thoughts on “How to consume a Lawson Web Service from a Personalized Script in Smart Office”

  1. Here’s a script example for a web service of type SQL from Karl G of Germany:

    function UpdateFloorStock() {
    try {
    // load the DLL
    var assembly = Assembly.LoadFrom(“http://host/LWS_DEV/PDS110Update.dll”);
    MessageBox.Show(assembly.GetTypes());
    // create a proxy
    var proxy = assembly.CreateInstance(“PDS110Update”);
    //MessageBox.Show(proxy);
    // SOAP Request Header (user and password)
    var header = assembly.CreateInstance(“headerType”);
    //MessageBox.Show(header);
    header.user = “myUser”;
    header.password = “myPassword”;
    proxy.mws = header;

    // SOAP Request Body (input parameters)
    var body = assembly.CreateInstance(“SQLGetProductsType”);
    body.pmfaci = “ZDA”;
    body.pmmtno = “LM98103662”;
    body.pmstrt = “STD”;
    // Call the web service
    var response = proxy.SQLGetProducts(body);
    var collection = response.SQLGetProductsRSCollection;
    for (var i in response.SQLGetProductsRSCollection) {
    MessageBox.Show(“PMCONO=” + collection[i].PMCONO + “, ” + “PMFACI=” + collection[i].PMFACI + “, ” + “PMFDAT=” + collection[i].PMFDAT + “, ” + “PMMSEQ=” + collection[i].PMMSEQ + “, ” + “PMOPNO=” + collection[i].PMOPNO + “, ” + “PMPRNO=” + collection[i].PMPRNO + “, ” + “PMSTRT=” + collection[i].PMSTRT);
    }
    }
    catch (err) {
    MessageBox.Show(err.ToException(err));
    }
    }

    Special thanks to Karl!

    Like

  2. I am trying to consume webservice via .NET but it is failing. I am getting following error :

    The M3 server returned error message ‘[FND0078] BCI Error: User must be entered ()’, code: 2,002

    I have created a proxy class by adding web reference in Visual studio for MPD_CRS111_Create web service. Here is my code to call it . We are using Movex Version 10.

    TestApp.V10TestWebServiceCRS111Create.MPDCRS111CreateService objService = new TestApp.V10TestWebServiceCRS111Create.MPDCRS111CreateService();

    TestApp.V10TestWebServiceCRS111Create.lws objLws = new TestApp.V10TestWebServiceCRS111Create.lws();

    System.Net.ICredentials credentials = new NetworkCredential(“myusername”, “mypassword”);

    objService.Credentials = credentials;
    objLws.user = “myusername”;
    objLws.password = “mypassword”;

    objService.lwsValue = objLws;

    TestApp.V10TestWebServiceCRS111Create.CreateType objCreateType = new TestApp.V10TestWebServiceCRS111Create.CreateType();

    TestApp.V10TestWebServiceCRS111Create.ct_0 ct0 = new TestApp.V10TestWebServiceCRS111Create.ct_0();

    ct0.ElectronicMailAddress=”abc@abc.net.au”;
    ct0.EmailType=”04″;
    ct0.EmailKeyValue=”vitagljo”;

    objCreateType.CRS111 = ct0;

    TestApp.V10TestWebServiceCRS111Create.CreateResponseType resType = objService.Create(objCreateType);

    TestApp.V10TestWebServiceCRS111Create.ct_1 res = resType.CRS111;

    What am i doing wrong here ? … Any input greatly appreciated …

    Like

  3. I was able to resolve the issue. It turn out that Movex does not like “lowercase” charachers in values. Anyways I learned my lesson heard way…wasting time on finding solution to the problem which was not actual problem. I changed my code from

    ct0.EmailKeyValue=”vitagljo”; to ct0.EmailKeyValue=”VITAGLJO”;

    and it worked perfectly … Seriously thogh the message returend from web service on the first instance was not clear at all. All the way I though there is something wrong with the way I supplied authentication credentials to the web service.

    Anyways back to Happy Coding !!!

    Like

    1. Tip: next time, use Fiddler to intercept the SOAP Request from LWS Studio (which is correct if the test case succeeds) and from your .NET code (which was failing in your case), and compare both XML to find the difference. That’s what I do for troubleshooting cases like this. You can also use soapUI.

      Like

    2. We are experiencing the same issue but it points to MNS212 see log below

      WebServicesFault
      faultCode: {http://schemas.xmlsoap.org/soap/envelope/}M3-4
      faultString: The M3 server returned error message ‘[FND0078] BCI Error: MNS212 not specified in script ()’, code: 2,002
      faultActor: null
      faultDetail:
      message: The M3 server returned error message '[FND0078] BCI Error: MNS212 not specified in script ()', code: 2,002

      The M3 server returned error message ‘[FND0078] BCI Error: MNS212 not specified in script ()’, code: 2,002
      at com.ibm.ws.webservices.engine.WebServicesFault.makeUserFault(WebServicesFault.java:226)
      at com.ibm.ws.webservices.engine.xmlsoap.builders.WebServicesFaultProcessor.createFault(WebServicesFaultProcessor.java:416)
      at com.ibm.ws.webservices.engine.xmlsoap.SOAPFault.getFault(SOAPFault.java:598)
      at com.ibm.ws.webservices.engine.SOAPPart.getFault(SOAPPart.java:1097)
      at com.ibm.ws.webservices.engine.SOAPPart.getFault(SOAPPart.java:754)
      at com.ibm.ws.webservices.engine.Message.getFault(Message.java:900)
      at com.ibm.ws.webservices.engine.Message.ifFaultThrowSelf(Message.java:880)
      at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:282)
      at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCHandler.invoke(JAXRPCHandler.java:152)
      at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:229)
      at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:229)
      at com.ibm.ws.webservices.engine.WebServicesEngine.invoke(WebServicesEngine.java:336)
      at com.ibm.ws.webservices.engine.client.Connection.invokeEngine(Connection.java:929)
      at com.ibm.ws.webservices.engine.client.Connection.invoke(Connection.java:722)
      at com.ibm.ws.webservices.engine.client.Connection.invoke(Connection.java:673)
      at com.ibm.ws.webservices.engine.client.Connection.invoke(Connection.java:495)
      at com.ibm.ws.webservices.engine.client.Stub$Invoke.invoke(Stub.java:977)
      at com.alternative.ws.b2bMomOrderConfirm.SCR_OIS605_OrderConfirmationSoapBindingStub.printConfirmation(SCR_OIS605_OrderConfirmationSoapBindingStub.java:147)
      at com.alternative.web.controller.SubmitOrderWSCalls.sendMomOrderConfirm(SubmitOrderWSCalls.java:90)
      at com.alternative.web.controller.SubmitOrderRunnable.postOrderProcessing(SubmitOrderRunnable.java:231)
      at com.alternative.web.controller.SubmitOrderRunnable.run(SubmitOrderRunnable.java:88)
      at org.springframework.scheduling.commonj.DelegatingTimerListener.timerExpired(DelegatingTimerListener.java:51)
      at com.ibm.ws.asynchbeans.timer.TimerImpl.callListenerMethod(TimerImpl.java:298)
      at com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:216)
      at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:257)
      at java.security.AccessController.doPrivileged(AccessController.java:214)
      at javax.security.auth.Subject.doAs(Subject.java:495)
      at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:118)
      at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:328)
      at java.security.AccessController.doPrivileged(AccessController.java:241)
      at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1111)
      at com.ibm.ws.asynchbeans.timer.TimerImpl.runListenerAsCJWork(TimerImpl.java:425)
      at com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:332)
      at com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:229)
      at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
      Caused by:
      javax.xml.rpc.soap.SOAPFaultException: The M3 server returned error message ‘[FND0078] BCI Error: MNS212 not specified in script ()’, code: 2,002
      at com.ibm.ws.webservices.engine.xmlsoap.builders.WebServicesFaultProcessor.createFault(WebServicesFaultProcessor.java:411)
      … 33 more

      Like

      1. Hi Tony. Yes, you are apparently missing the MNS212 node in your SOAP Request Body. You probably have a web service with Related Programs. Run your web service in SoapUI, or capture in Fiddler a test case from LWS Designer, and compare that with the SOAP Request you are sending with your Java code. You will see yours is missing a node in the tree. How to fix it will depend on your SOAP client. Where are you calling your web service from?

        Like

Leave a reply to Virang Cancel reply