09-24-2010 03:49 PM
Hi,
I made a .NET dll containing a Service Reference built based on a WSDL file.
In the VS2008 solution, I also have a console to test it and everything works fine. I can create the client by giving as a parameter the endpoint that match a xml node in the app.config file of the DLL.
To work, the executable console must also have an app.config with the same endpoint definition. Otherwise, you have this error:
The instance of the .NET class could not be retrieved.
Could not find endpoint element with name 'A400TMaintenanceSOAP' and contract 'ServiceReference400T.A400TMaintenance' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.
Now when I call the dll from TestStand, I have this error and I assume it's because the endpoint is not defined anywhere for TestStand. I tried to copy a SeqEdit.exe.config file next to the SeqEdit.exe with the endpoint defined (like the console in my c# project), but it didn't work.
Is there a way I can make it work so I can call the dll from de sequence editor?
I've attached the app.config file of my dll project (created automaticaly based on the WSDL file).
Thank for your time.
-Mat
Solved! Go to Solution.
09-29-2010 06:02 PM
Hey Mat,
As far as I know I would have expected placing a SeqEdit.exe.config file next to the SeqEdit.exe file to work. What version of TestStand are you using?
Also, could you provide me with the DLL that you are calling into so I can try and reproduce this here on my end?
Lars L
NI Applications Engineer
09-30-2010 12:33 AM
Hi Mat,
This sounds that you have the same issue than i had.
just visit this thread and add code snippets that Doug had suggested.
http://forums.ni.com/t5/NI-TestStand/Loading-app-config-stuff-from-net-assembly/td-p/1052769
After doing it i was able to load my config stuff from a Teststand step.
Hope this helps
Juergen
10-01-2010 08:46 AM
I tried to add the code of doug in my dll.
static bool assemblyResolveRegistered = false;
// Call this from your sequence before anything else. It only needs to be done once.
// That's why a static bool variable is used to check to see if it's already been done.
public static void RegisterAssemblyResolveEventHandler()
{
if (!assemblyResolveRegistered)
{
AppDomain.CurrentDomain.AssemblyResolve += new System.ResolveEventHandler(AssemblyResolveEventHandler);
assemblyResolveRegistered = true;
}
}
// This just needs to be in the same assembly as the RegisterAssemblyResolveEventHandler() method.
// This is the event handler that gets registered.
static System.Reflection.Assembly AssemblyResolveEventHandler(System.Object sender, System.ResolveEventArgs args)
{
if (args.Name.StartsWith("400T_IndusTestDLL")) // Change this to the name of your assembly
return System.Reflection.Assembly.GetExecutingAssembly();
else
return null;
}
It didn't change anything. There's a config file next to the SeqEdit.exe (SeqEdit.exe.config) and another one with the same content next to dll (400T_IndusTestDLL.dll.config).
I call RegisterAssemblyResolveEventHandler() in a .NET step in TestStand, then call my function and I get the same error. I placed a breakpoint in the AssemblyResolveEventHandler and it actually never gets triggered.
The dll compiled with it's .config file and the seq file are in attachment. The function I called that generates the error is below. The line in bold is where the error happens.
public static int SOAP_EnterMaintenance(ref int errorCode, ref string errorMessage)
{
try
{
ServiceReferenceSOAP_400T.A400TMaintenanceClient client400T = new _400T_IndusTestDLL.ServiceReferenceSOAP_400T.A400TMaintenanceClient("A400TMaintenanceSOAP", "http://10.1.2.25:18001");
return client400T.EnterMaintenance();
}
catch (Exception e)
{
errorMessage = e.Message + "\r\n" + e.Data.ToString();
errorCode = 802;
return -1;
}
}
Thank you.
10-01-2010 09:14 AM
Hi,
I did it this way in C#
....
RegisterAssemblyResolveEventHandler();
// Map the new configuration file.
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = strConfigPath; // path to the config file.
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);"MySection") as MyConfig; // When setting Breakpoint here you will jump into AssemblyResolveEventHandler
....
Hope this Helps
Juergen
m_MyConfig = config.GetSection(
10-01-2010 09:18 AM
HEY WHAT Happens to the format !!!!!!
ONCE MORE AGAIN
Hi,
I did it this way in C#
....
RegisterAssemblyResolveEventHandler();
// Map the new configuration file.
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = strConfigPath; // path to the config file.
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
m_MyConfig = config.GetSection("MySection") as ZkpDialogSection; // When setting Breakpoint here you will jump into AssemblyResolveEventHandler
....
Hope this Helps
Juergen
10-01-2010 10:15 AM
I think you might have a mistake in your config file. The error message says, "Could not find endpoint element with name 'A400TMaintenanceSOAP' and contract 'ServiceReference400T.A400TMaintenance' in the ServiceModel client configuration section", yet your config file has:
<endpoint address="http://localhost/A400TMaintenance/" binding="basicHttpBinding"
bindingConfiguration="A400TMaintenanceSOAP" contract="A400T_Maintenance.A400TMaintenance"
name="A400TMaintenanceSOAP" />
So it looks like you've got the contract name wrong in one place or the other (most likely in the config file). I do not think you will need assembly resolve in this case. I think you can use a config file for seqedit.exe like you originally had.
Hope this helps,
-Doug
10-01-2010 10:47 AM
Yes you are right Doug. Actually, the config file was from the other solution that was working on his own, but I still had a mismatch on the dll config file also (renaming earlier in the project).
So it works when I place the config file SeqEdit.exe.config, but is there a way that I don't have to do that? I would prefer to have the config file next to the dll since it's easier for deployment.
The latest code posted by Juergen could allow me to do that?
10-01-2010 11:32 AM - edited 10-01-2010 11:34 AM
I haven't used web services much myself, but I strongly suspect that you can create the binding programmatically rather than using a config file. At least you can do so for .NET remoting so I think it's very likely you can do so for web services as well. This is probably a good starting point in the Microsoft documentation if you want to go this route:
http://msdn.microsoft.com/en-us/library/abffc213%28v=VS.80%29.aspx
http://msdn.microsoft.com/en-us/library/system.web.services.description.binding%28v=VS.80%29.aspx
You do not need assembly resolve, the reason Juergen needed assembly resolve is because the types serialized in his config file were from his assembly, your config file only has types from the system assemblies.
It might be possible to load the config file from the directory of the dll rather than from the exe, but again, this is not something I've tried to do so I don't know the exact details for doing so. Perhaps the APIs that Juergen was using are the same ones you'd need to use to do this. You might want to do some searching through msdn documentation or post to Microsoft's support website for more details.
Hope this helps,
-Doug
10-15-2010 12:08 PM
Thank you dug and j_dodek for your help.
It's working by renaming the app.config to SeqEdit.exe.config and placing it next to the SeqEdit.exe.
Same for my GUI, so I have a GUI.exe.config file with the endpoint config as well.
This solution is ok since I don't modify this file often and the endpoint details are now part of my GUI solution app.config.
Thank you.