Question Status

Verified
LeeRoberts asked a question on 3 May 2013 2:11 AM

// connect to Dynamics AX

Axapta ax;

System.Net.NetworkCredential networkCredential = new System.Net.NetworkCredential();

networkCredential.UserName = "Administrator"; //Ax >> Administration >> Setup >> Security >> Business connector Proxy account field)

networkCredential.Password = "myPassword";

networkCredential.Domain = "myDoamin";

ax.LogonAs("Administrator", "myDoamin", networkCredential, "dat", "en-us", "01@DEV-PI-AX2009:2712", "");

axContainer = (AxaptaContainer)ax.CallStaticClassMethod("AifServiceReferenceManager", "generate", "http://myServerIP/myFolder/DynamicsAxIntegrationService.svc?wsdl", "myRegisteredServiceName", true);

Reply
Martin Dráb responded on 3 May 2013 2:50 AM

And what's the problem?Do you get any errors? Does you code work if called directly from X++?  Are you able to connect at all?

By the way, you say that you're "Not able to register a WCF service (into Reference folder in AOT)", but generate() doesn't add a service reference to AOT, so you may be waiting for something that will never happen.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
LeeRoberts responded on 3 May 2013 4:02 AM

The code runs with no exceptions - but no service is added to the AOT?

You add intrigue to my question, what class\methods would I need then to call to register the service within Dax?

NB Does AifServiceReferenceManager::Generate just generate the assembly (proxy) on the server and not register it within the AOT?

Reply
Suggested Answer
Martin Dráb responded on 3 May 2013 4:29 AM

That's right, generate() creates the WCF service proxy, it doesn't do anything in AOT. The XML documentation of generate() says: "Generates WCF artifacts for the web reference and stores them in the application directory". Look at the code to understand exactly what and how it does.

How to add references to AOT was discussed in How to register (signed) external assembly using CallStaticClassMethod; it applies to service references too.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
LeeRoberts responded on 3 May 2013 4:50 AM

OK I see whats happening - it's a two step process.

1) Run AifServiceReferenceManager::Generate to get the service proxy created on the server

2) Run SysReference(....).addToAOT(); to get the service displayed

So my question now is:

In BC.Net using CallStaticClassMethod how do I call a non-static method like "new SysReference(....).addToAOT()"

-------------------------------------------------------------------------------------------------------------------------------------------

new SysReference( str _name, str _assemblyName, str _displayName, str _culture,

               str _publicKeyToken, int _majorVersion = 0, int _minorVersion = 0,

               int _buildNumber = 0, int _revisionNumber = 0, str _version = "",

               boolean _serviceReference = false, str _wsdlUrl = "",

               str _dotNetCodeNamespace  = "", str _serviceDescription = "")

Reply
Suggested Answer
Martin Dráb responded on 3 May 2013 5:14 AM

As the name suggests, CallStaticClassMethod() is used for calling static methods. To create an object, use CreateAxaptaObject(). Then use Call() method of the object to invoke instance methods.

See the documentation for details.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
LeeRoberts responded on 3 May 2013 6:32 AM

When calling the "CreateAxaptaObject" method - I get "method new called with invalid parameters"

AxaptaObject assembly;
object[] sysParams = new object[6];
object[] sysSubParams = new object[9];

sysSubParams[0] = 1;
sysSubParams[1] = 0;
sysSubParams[2] = 0;
sysSubParams[3] = 0;
sysSubParams[4] = "";
sysSubParams[5] = false;
sysSubParams[6] = "";
sysSubParams[7] = "";
sysSubParams[8] = "";

sysParams[0] = "Ae14499e27b9d4c338edad26e52eb1248";
sysParams[1] = "Ae14499e27b9d4c338edad26e52eb1248.dll";
sysParams[2] = "ErrorAndLocalisation";
sysParams[3] = "en-us";
sysParams[4] = "";
sysParams[5] = sysSubParams;

assembly = (AxaptaObject)ax.CreateAxaptaObject("SysReference", sysParams);
assembly.Call("addToAOT");

Reply
Verified Answer
Martin Dráb responded on 3 May 2013 6:54 AM

What do you want to hear? The error message is 100% correct - you call new() with invalid parameters.
You call it with six parameters, where the sixth one is an array of objects. But the sixth parameter of the constructor has type of int, which is incompatible with the array.

Use just one array. This is an example with all parameters (including optional):

object[] sysParams = new object[]
{
    "Ae14499e27b9d4c338edad26e52eb1248",
    "Ae14499e27b9d4c338edad26e52eb1248.dll",
    "ErrorAndLocalisation",
    "en-us",
    "",
    1,
    0,
    0,
    0,
    "",
    false,
    "",
    "",
    ""
};

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
LeeRoberts responded on 3 May 2013 8:42 AM

Thanks for that - every little bit is pushing me forward, but :) I get the follwoing error message after making the  "CALL"

"The requested X++ operation is not supported. Set property failed."

I'm not 100% sure if the parameters are correct - in that should I be passing the full path to the dll on the server (which the aif::generate installed previously)

object[] sysParams = new object[]
{
"Ae14499e27b9d4c338edad26e52eb1248",
"Ae14499e27b9d4c338edad26e52eb1248.dll",
"ErrorAndLocalisation",
"en-us", "", 0, 0, 0, 0, "", false, "", "", ""
};

assembly = (AxaptaObject)ax.CreateAxaptaObject("SysReference", sysParams);

assembly.Call("addToAOT");

Reply
Martin Dráb responded on 5 May 2013 2:28 AM

It works in AX2012, but it's obviously not supported by AX2009.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
LeeRoberts responded on 7 May 2013 1:06 AM

But that is surprising (for AX 2009) since the classes are there to do it?

And because you can use "AifServiceReferenceManager::Generate" to generate a WCF assembly onto the server bin folder but not able to use the accompanying "SysReference" method to get it registered within the AOT - that's just strange?

Where can more information\help be found on this as the online documentation is very very sparse on  SysReference (there looks to be confusing concerning the parameter list going by the help doc and what the function actually wants)?

Reply
Martin Dráb responded on 7 May 2013 1:15 AM

The class works fine if you use it in normal AX client; it seems to be a limitation of Business Connector in AX2009. I know that BC works with application objects in a different way than the full AX client, but I don't have any details about how it's actually implemented.

I don't think you will find any documentation, it's not something what people normally use. Just check out how the standard code uses that.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
Verified Answer
Martin Dráb responded on 3 May 2013 6:54 AM

What do you want to hear? The error message is 100% correct - you call new() with invalid parameters.
You call it with six parameters, where the sixth one is an array of objects. But the sixth parameter of the constructor has type of int, which is incompatible with the array.

Use just one array. This is an example with all parameters (including optional):

object[] sysParams = new object[]
{
    "Ae14499e27b9d4c338edad26e52eb1248",
    "Ae14499e27b9d4c338edad26e52eb1248.dll",
    "ErrorAndLocalisation",
    "en-us",
    "",
    1,
    0,
    0,
    0,
    "",
    false,
    "",
    "",
    ""
};

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
Suggested Answer
Martin Dráb responded on 3 May 2013 4:29 AM

That's right, generate() creates the WCF service proxy, it doesn't do anything in AOT. The XML documentation of generate() says: "Generates WCF artifacts for the web reference and stores them in the application directory". Look at the code to understand exactly what and how it does.

How to add references to AOT was discussed in How to register (signed) external assembly using CallStaticClassMethod; it applies to service references too.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply
Suggested Answer
Martin Dráb responded on 3 May 2013 5:14 AM

As the name suggests, CallStaticClassMethod() is used for calling static methods. To create an object, use CreateAxaptaObject(). Then use Call() method of the object to invoke instance methods.

See the documentation for details.

Martin "Goshoom" Dráb | Freelancer | Goshoom.NET Dev Blog

Reply