Reputation: 31
We have added a C# project to our AX environment. We recently made modifications to the app.config file, cleaned and rebuilt the project, and deployed it to the AOT. If I go into the SqlServer Management Studio and query the VSASSEMBLIES table, I can see the corresponding .dll and .dll.config files. I dumped the content for the .dll.config and converted it back to text to make sure the version in the table is the most recent, and it is.
The problem is that the .dll.config file is never getting written out to disk (C:\Program Files\Microsoft Dynamics AX\60\Server[Instance]\bin\VSAssemblies) when the AOS restarts. The .dll gets written out, but not the config. If I wipe out the entire directory and restart the AOS, everything gets written back out except our config file.
The config file for EInvoiceCFDI_MX.dll gets written out, so I have scoured their project files and configurations and cannot come up with anything they have set that we don't.
The only thing I see is in the AOT is the EInvoiceCFDI_MX project shows the .dll.config file under Project Output where ours does not. I checked the intermediate targets referenced by the default build script and it clearly shows that the app.config should be getting copied to the project output, but for some reason it is not.
What am I missing?
Jan, thanks for your post.
We are constructing/configuring the service in the way you referenced:
CLRObject clientType = CLRInterop::getType("OurService");
OurService client = AifUtil::createServiceClient(clientType);
The createServiceClient() is throwing an exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the
target of an invocation. ---> System.InvalidOperationException: Unable to find
the application configuaration file C:\Users\<user>\AppData\Local\Microsoft\
Dynamics Ax\VSAssemblies\OurService.dll.config.
The OurService.dll.config file is in the AOT, but it is not getting written out to disk when the server or client is started.
Upvotes: 3
Views: 3611
Reputation: 894
What changes are included in the config file?
If it's addresses that you want to modify, you can also eliminate the need of a config file and configure the bindings yourself based on parameters that you store in you Ax environment.
For example, when you have create an external service and you want to call it from Ax, but DEV / TST / PRODUCTION have different URL's. Instead of adding the addresses and binding information in a config file, you can specifiy this when creating your client.
below is a piece of code that manually alters the EndPoint and puts in the value we want. (you could put the values in parameters off course so that you can setup this per environment.
static void Consume_GetZipCodePlaceNameWithEndPoint(Args _args)
{
DynamicsAxServices.WebServices.ZipCode.USAZipCodeServiceRef.PostalCodeServiceClient postalServiceClient;
DynamicsAxServices.WebServices.ZipCode.USAZipCodeServiceRef.PostalCodepostalCode;
System.ServiceModel.Description.ServiceEndpoint endPoint;
System.ServiceModel.EndpointAddress endPointAddress;
System.Exception exception;
System.Type type;
;
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();
}
}
}
Upvotes: 1
Reputation: 21
In your visual Studio Project go to the properties of the app.config
file and set the following properties:
(not sure if the Translation of the properties is correct because I have the German Version...)
Upvotes: 2
Reputation: 18061
Did you change the global app.config? Don't!
Instead make the project config file available using AifUtil::CreateServiceClient
as explained here.
Change the config file? This would work, but the class library's config file is stored in the model store and downloaded by the client/server. It can't be changed unless it's changed in the AOT, the Visual Studio project is rebuilt, at which point the client/server will download the new version from the model store. So, you could copy/paste all the app.config settings into the AX32(serv).exe.config file and change it there. Then you won't need to use the aifUtil::createserviceclient. In any case, this is very impractical, especially for services running on the client side!
From the Technet article: The following example code shows how to construct and configure a service client object for the Bing service. To use the web service, you must use this code in your Microsoft Dynamics AX program to enable the service reference to construct and configure an instance of a service client.
// Retrieve the X++ type for the Bing service client object.
ClrObject clientType = CLRInterop::getType("BingSearch.ServiceReferences.BingV2ServiceReference.BingPortTypeClient");
// Use the AifUtil class to create an instance of the service client object.
BingSearch.ServiceReferences.BingV2ServiceReference.BingPortTypeClient client = AifUtil::CreateServiceClient(clientType);
Upvotes: 1