2

I have consumed a web service using visual studio and used managed code to call that in AX 2012. Now if I am running the code in a simple job as:

static void CurrencyService(Args _args)
{
   CurrencyConvert.Currency_Convert.CurrencyServiceClient convertcurrency;
   CurrencyConvert.Currency_Convert.Currency currency;
   System.ServiceModel.Description.ServiceEndpoint endPoint;
   System.Type type;
   System.Exception ex;
   str s1;

try
{
    type = CLRInterop::getType('CurrencyConvert.Currency_Convert.CurrencyServiceClient');
    convertcurrency = AifUtil::createServiceClient(type);

    endPoint = convertcurrency.get_Endpoint();
   // endPoint.set_Address(new System.ServiceModel.EndpointAddress("http://localhost/HelloWorld"));
    currency = convertcurrency.GetConversionRate(CurrencyConvert.Currency_Convert.CurrencyCode::AUD,CurrencyConvert.Currency_Convert.CurrencyCode::INR );

  info(strFmt('%1', CLRInterop::getAnyTypeForObject(currency.get_Rate())));
}
 catch(Exception::CLRError)
{
    ex = CLRInterop::getLastException();
    info(CLRInterop::getAnyTypeForObject(ex.ToString()));
}
}

Above job is working fine and producing results in a infolog.

Now, if a same piece of code is written under a class for batchjob(extending Runbasebatch class) as we normally do for any batch job, it is throwing an error as:

Microsoft.Dynamics.Ax.Xpp.ErrorException: Exception of type 'Microsoft.Dynamics.Ax.Xpp.ErrorException' was thrown.

at Dynamics.Ax.Application.BatchRun.runJobStatic(Int64 batchId) in BatchRun.runJobStatic.xpp:line 38

at BatchRun::runJobStatic(Object[] )

at Microsoft.Dynamics.Ax.Xpp.ReflectionCallHelper.MakeStaticCall(Type type, String MethodName, Object[] parameters)

at BatchIL.taskThreadEntry(Object threadArg)

Other batch jobs except which used web services are working properly. I have already tried many things such as : RunOn property of a class is set as "server" etc. This is the case with each web service we have consumed. Does anybody have a proper solution for this??

AnthonyBlake
  • 2,334
  • 1
  • 25
  • 39
Mohd Saddaf khan
  • 289
  • 2
  • 14
  • 26
  • Have you create class that extends from AifDocumentService and setup batch job for this class ? – Setiaji Dec 10 '13 at 07:59
  • @Setiaji As much as i know, to use a class in batch job i think we have to create class extending "RunBaseBatch" class. Please correct me if i am wrong?? – Mohd Saddaf khan Dec 10 '13 at 09:00
  • Thats correct, i was telling you that you could test your script inside the class extends AifDocumentService class, and setup batch job for this class. For example (in class declaration) : class onHandServices extends AifDocumentService {} – Setiaji Dec 10 '13 at 09:42
  • hi @MohdSaddafkhan - is your error thrown only when running in batch queue, or do you see the error when you run manually via the batch dialog? – AnthonyBlake Dec 11 '13 at 09:06
  • @AnthonyBlake - issue occurs only when running in batch queue, otherwise it is working fine. – Mohd Saddaf khan Dec 11 '13 at 13:12
  • Has the visual studio project been marked as Deploy to server as well? You may also want to add more debug code in the catch method to find out what type of exception is being thrown. – Looneystar Dec 16 '13 at 21:36

3 Answers3

1

I am assuming that this is the same as on the Dynamics Ax community site post. So reading there, the error is not related to batch but to the following: "Could not find default endpoint element that references contract 'Currency_Convert.ICurrencyService' in the ServiceModel client configuration section.

This is because the endpoint is being searched in the AX32.exe.config file and this is not the one you need. You need to get it from the config file associated with your DLL.

To do this, you need to construct you client differently in AX. You need to use the AIF util because that way, the right config is used. Example:

type= CLRInterop::getType('DynamicsAxServices.WebServices.ZipCode.USAZipCodeServiceRef.PostalCodeServiceClient'); 
postalServiceClient = AifUtil::createServiceClient(type);

Apart from that, there is also an extra thing to whatch for. Separate environments would require different URL's and this can be solved by manually specifying your endpoint address and let it use a system parameter. (that way you can specify different configurations for DEV/TEST/PROD) (Note: below the endpoint address is hard coded and that should be a parameter)

static void Consume_GetZipCodePlaceNameWithEndPoint(Args _args) 
{  
    DynamicsAxServices.WebServices.ZipCode.USAZipCodeServiceRef.PostalCodeServiceClient postalServiceClient;  
    DynamicsAxServices.WebServices.ZipCode.USAZipCodeServiceRef.PostalCodepostalCode;  
    System.ServiceModel.Description.ServiceEndpointendPoint;  
    System.ServiceModel.EndpointAddressendPointAddress;  
    System.Exceptionexception;  
    System.Typetype;  
    ;

    try
    {
        // Get the .NET type of the client proxy   
        type = CLRInterop::getType('DynamicsAxServices.WebServices.ZipCode.USAZipCodeServiceRef.PostalCodeServiceClient');

        // Let AifUtil create the proxy client because it uses the VSAssemblies path for the config file    
        postalServiceClient = AifUtil::createServiceClient(type);

        // Create and endpoint address, This should be a parameter stored in the system
        endPointAddress = new System.ServiceModel.EndpointAddress ("http://www.restfulwebservices.net/wcf/USAZipCodeService.svc");

        // Get the WCF endpoint    
        endPoint = postalServiceClient.get_Endpoint();

        // Set the endpoint address.    
        endPoint.set_Address(endPointAddress);

        // Use the zipcode to find a place name    
        postalCode = postalServiceClient. GetPostCodeDetailByPostCode("10001"); // 10001 is New York

        // Use the getAnyTypeForObject to marshal the System.String to an Ax anyType    
        // so that it can be used with info()    
        info(strFmt('%1', CLRInterop::getAnyTypeForObject(postalCode.get_ PlaceName())));  
    }  
    catch(Exception::CLRError)  
    {    
        // Get the .NET Type Exception     
        exception = CLRInterop::getLastException();

        // Go through the inner exceptions    
        while(exception)    
        {      
            // Print the exception to the infolog      
            info(CLRInterop::getAnyTypeForObject(exception.ToString()));

            // Get the inner exception for more details      
            exception = exception.get_InnerException();    
        }
    }
}
Kenny Saelen
  • 894
  • 1
  • 5
  • 16
1

I was getting the same issue, finally its resolved. Login to AOS machine with AOS service account and check if you can browse internet. If not then you need to set proxy for internet in IE. So basically under AOS account, process could not connect to Webservice provider.

1

I have resolved this issue. I just end session all online user and stop/start AOS after doing ful cil. Maybe deleting XPPIL and Appl files helps before start the AOS service.

Vahid
  • 11
  • 1