Forum Discussion
Mark_Scattergoo
Nimbostratus
Feb 02, 2005XML exception when calling ITCMLocalLBVirtualServer.get_virtual_address_list()
I'm writing some iControl code (using iControl 4.6.2) for use against a
540 running 4.5.9 Build 2 and a 2400 running 4.5 PTF3. When I call
ITCMLocalLBVirtualServer.get_virtual_address_list() from the 540, I get the following exception (XML error), but the same code works from the 2400. Is there a known bug in 4.5.9 Build 2? I looked through the release notes for later releases but didn't find any references to this problem.
TIA.
System.InvalidOperationException: There is an error in XML document (11,
2). ---> System.InvalidOperationException: The specified type was not
recognized: name='ITCMCommon.IPAddress', namespace='urn:iControl', at xmlns=''>.
at
System.Xml.Serialization.XmlSerializationReader.GetPrimitiveType(XmlQualifiedNam
e typeName, Boolean throwOnUnknown)
at System.Xml.Serialization.XmlSerializationReader.ReadArray(String
typeName, String typeNs)
at
System.Xml.Serialization.XmlSerializationReader.ReadReferencingElement(String
name, String ns, Boolean elementCanBeType, String& fixupReference)
at
System.Xml.Serialization.XmlSerializationReader.ReadReferencingElement(String
name, String ns, String& fixupReference)
at
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read390_ge
t_virtual_address_listResponse()
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
xmlReader, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
xmlReader)
at
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMess
age message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String
methodName, Object[] parameters)
at
BigIpPoC.F5VirtualServer.ITCMLocalLBVirtualServer.get_virtual_address_list(Strin
g[]& vlan_wildcard_addresses) in c:\workspace\bigippoc\web
references\f5virtualserver\reference.cs:line 1974
at BigIpPoC.Class1.Main(String[] args) in c:\workspace\bigippoc\class1.cs:line 51
12 Replies
- Loc_Pham_101863Historic F5 AccountAs far as I could tell, the code for this method is identical between the 2 releases, 4.5.9 Build 2 and 4.5 PTF3.
I don't know for sure yet whether this is the culprit, but from what I see in the exception stack below:
BigIpPoC.F5VirtualServer.ITCMLocalLBVirtualServer.get_virtual_address_list(String[]& vlan_wildcard_addresses) in c:\workspace\bigippoc\web
references\f5virtualserver\reference.cs:line 1974
it shows you only have 1 parameter in the call to get_virtual_address_list, where it should have taken 2 parameters. Can you post a snippet of the code calling this method? It would help us track down the issue better.
Thanks,
Loc - Mark_Scattergoo
Nimbostratus
Loc - thanks for the response. According to the documentation I have, get_virtual_address_list takes one argument and returns a string[]. Here is some sample code to reproduce the problem. I can take this code, change the IP address in the webservice URL from the 540 to the 2400, and have it work fine.using System; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Web; namespace BigIpPoC { class Class2 { [STAThread] static void Main(string[] args) { ServicePointManager.CertificatePolicy = new CertPolicy(); F5VirtualServer.ITCMLocalLBVirtualServer bigIpVirtualServer = new F5VirtualServer.ITCMLocalLBVirtualServer(); bigIpVirtualServer.Url = "https:///iControl/iControlPortal.cgi"; bigIpVirtualServer.PreAuthenticate = true; bigIpVirtualServer.Credentials = new NetworkCredential("", @"", ""); string[] bigIpVlanWildcardArresses; try { string[] virtualAddressList = bigIpVirtualServer.get_virtual_address_list(out bigIpVlanWildcardArresses); } catch (Exception e) { Console.Write(e.ToString()); } } } public class CertPolicy : ICertificatePolicy { public CertPolicy() { // Nothing to do. } public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return(true); } } } - Loc_Pham_101863Historic F5 AccountAccording to 4.6.2 SDK documentation, the signature for get_virtual_address_list is:
void get_virtual_address_list( in SessionCredentials creds, <== CORBA Specific out String[] virtual_addresses, out String[] vlan_wildcard_addresses );
I'll try to reproduce this problem against a BIG-IP 4.5.9 and will let you know what I find.
Thanks,
Loc - Mark_Scattergoo
Nimbostratus
I would guess that the definition that you show is for the CORBA interface. I'm using SOAP/XML. The web method is declared as:
[System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:iControl:ITCMLocalLB/VirtualServer", RequestNamespace="urn:iControl:ITCMLocalLB/VirtualServer", ResponseNamespace="urn:iControl:ITCMLocalLB/VirtualServer")]
[return: System.Xml.Serialization.SoapElementAttribute("virtual_addresses")]
public string[] get_virtual_address_list(out string[] vlan_wildcard_addresses) {
object[] results = this.Invoke("get_virtual_address_list", new object[0]);
vlan_wildcard_addresses = ((string[])(results[1]));
return ((string[])(results[0]));
}
Thanks for your assistance so far. Let me know what you find out.
-Mark - Loc_Pham_101863Historic F5 AccountMark,
According to the SDK documentation, the method signature is like below(ignore the param specific to CORBA). The WSDL will also have two params in the request:void get_virtual_address_list( in SessionCredentials creds, <== CORBA Specific out String[] virtual_addresses, out String[] vlan_wildcard_addresses );
The signature you saw/gave is just how most SOAP client toolkits deserialize the OUT parameters.
Anyways, I've reproduced this problem internally. And we've put a fix in for this in 4.6.2. I don't know why it worked for you in 4.5 PTF 03.... BTW, this is a problem specific to the way .NET deserializes data, and our fix was a work-around for this MS-specific bug.
Loc - Loc_Pham_101863Historic F5 AccountMark,
I'm using VS.Net 2003, and I don't currently see the "Bad Request" problem. Using similar code framework (with different interfaces, of course) as below, I'm able to communicate with various versions of BIG-IP (4.x, 4.6.x, 9.x). I'm including some code below so you can reference. Please let us know if this helps.
This is my main C file, ITCMVirtualServerMain.csusing System; using ITCMVirtualServer.ITCMVirtualServerWebRef; namespace ITCMVirtualServer { /// /// Summary description for Class1. /// class Class1 { private ITCMLocalLBVirtualServer vsObj; private System.Net.NetworkCredential creds; private string sHostname = ""; private string sPort = ""; private string sUsername = ""; private string sPassword = ""; private string [] months = new string[12]; /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { System.Net.ServicePointManager.CertificatePolicy = new iControlCertificatePolicy(); Class1 itcmVS = new Class1(); itcmVS.processArgs(args); try { itcmVS.getVirtualAddressList (); } catch (System.InvalidOperationException ioe) { Console.WriteLine (ioe.ToString()); } } public void processArgs(string []args) { vsObj = new ITCMLocalLBVirtualServer(); creds = new System.Net.NetworkCredential(); vsObj.Credentials = creds; if ( args.Length < 4 ) { usage(); } else { sHostname = args[0]; sPort = args[1]; sUsername = args[2]; sPassword = args[3]; months[0] = "January"; months[1] = "February"; months[2] = "March"; months[3] = "April"; months[4] = "May"; months[5] = "June"; months[6] = "July"; months[7] = "August"; months[8] = "September"; months[9] = "October"; months[10] = "November"; months[11] = "December"; updateConnectionInfo(); } } public void usage() { Console.WriteLine("Usage: ITCMVirtualServer host port username password"); } private void updateConnectionInfo() { creds.UserName = sUsername; creds.Password = sPassword; string sProtocol = "http://"; if (sPort.Equals ("443")) sProtocol = "https://"; vsObj.Url = sProtocol + sHostname + ":" + sPort + "/iControl/iControlPortal.cgi"; vsObj.PreAuthenticate = true; } public void printException(System.Web.Services.Protocols.SoapHeaderException soapHdrEx) { Console.WriteLine(soapHdrEx.Message); } private void getVirtualAddressList() { try { Console.WriteLine("=============================================="); Console.WriteLine("Virtual address list"); Console.WriteLine("-------------------"); string [] vlanWildCardList; string [] virtualAddressList = vsObj.get_virtual_address_list (out vlanWildCardList); if (vlanWildCardList.Length == 0 && virtualAddressList.Length == 0) Console.WriteLine ("No virtual addresses"); else { Console.WriteLine ("Virtual addresses:"); if (virtualAddressList.Length == 0) Console.WriteLine (" None"); else { for (int i = 0; i < virtualAddressList.Length; i++) { Console.WriteLine(" [" + i + "] " + virtualAddressList[ i ]); } } Console.WriteLine ("VLAN wildcard addresses:"); if (virtualAddressList.Length == 0) Console.WriteLine (" None"); else { for (int i = 0; i < vlanWildCardList.Length; i++) { Console.WriteLine(" [" + i + "] " + vlanWildCardList[ i ]); } } } Console.WriteLine("=============================================="); } catch (System.Web.Services.Protocols.SoapHeaderException soapHdrEx) { printException(soapHdrEx); } } } }
This is the file that handles certificate and authentication, iControlCertificatePolicy.cs:using System; using System.Security; using System.Net; using System.Security.Cryptography.X509Certificates; namespace ITCMVirtualServer { /// /// Summary description for iControlCertificatePolicy. /// public class iControlCertificatePolicy : System.Net.ICertificatePolicy { public iControlCertificatePolicy() { // // TODO: Add constructor logic here // } public bool CheckValidationResult(System.Net.ServicePoint sp, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Net.WebRequest request, int problem) { return true; } } } - You are dealing with 2 different problems here.
1. WSDL indicates incorrect return type of long[] instead of string[].
This is a problem with the WSDL in the 4.6.2 SDK. The server will return the correct type of "string" for IPAddresses but the WSDL specifies an incorrect value of "long". I'm working on an update to the 4.6.2 SDK and this issue will be fixed with version 4.6.3. I'll post here when I get an updated SDK posted to DevCentral.
2. Upgrading to 4.6.2 caused Invalid web requests
This is a known issue in Apache in it's handling of keep-alives with POST data. VS.NET will use a Keep-Alive connection by default and your trace indicates a HTTP format error which is what we have reproduced here.
This has been fixed in 4.6.3. As a temporary measure you can turn off Keep-Alives by modifying the following line in the /config/bigconfig/httpd.conf file on your BIG-IP.KeepAlive On
toKeepAlive Off
-Joe - Loc_Pham_101863Historic F5 AccountSince I was testing against Joe's BIGIP, and w/ his Apache's KeepAlive setting being Off, that's probably why I didn't see the "Bad Request" problem which Mark described.
Loc - Mark_Scattergoo
Nimbostratus
Joe - thanks for the response. Turning off KeepAlives is not (to me) a really great solution for obvious performance reasons. Overiding the WebRequest object and manually setting the authentication header in each request works fine, and is probably a better work around. I hate to appear that I have been labouring the point, but I
wanted to be sure that F5 understood that there were three problems, which are:
1. get_virtual_address_list() is broken in 4.5.9 Build 2 (and possibly others).
Loc explained that this was a known interop issue with Microsoft's XML parser, and that a patch had been implemented in 4.6.2, so I have upgraded to 4.6.2.
2. The return type of get_virtual_address_list() had changed incorrectly from string[] to long[] in the WSDL in the 4.6.2 firmware.
I had already fixed that by modifying the proxy class to specify the correct return type (and pinning a reminder note on my forehead to not update the web reference...). Incidentally, the WSDL in 4.5.9 Build 2 is correct so I could also have imported it.
3. 4.6.2 introduces Apache changes which breaks Basic authentication with a Microsoft .Net web services client due to the web services client's incorrect handling of a 401 response. As you suggest, this could be fixed by disabling KeepAlives, or implementing the following code.using System; using System.Net; using System.Web; namespace BigIpPoC { public class F5VirtualServerWebRequest : F5VirtualServer.ITCMLocalLBVirtualServer { private string username = null; private string password = null; public F5VirtualServerWebRequest( string Username, string Password) { if (Username == null || Username.Length == 0) throw(new Exception("Username parameter is null or empty")); else if (Password == null || Password.Length == 0) throw(new Exception("Password parameter is null or empty")); else { username = Username; password = Password; } } protected override WebRequest GetWebRequest( Uri uri) { HttpWebRequest webRequest = (HttpWebRequest) base.GetWebRequest(uri); string authInfo = username + ":" + password; char[] authBuffer = authInfo.ToCharArray(); byte[] byteArray = new byte[authBuffer.Length]; for (int i = 0; i < authBuffer.Length; i ++) { byteArray[ i ]= Convert.ToByte(authBuffer[ i ]); } webRequest.Headers.Add("Authorization: BASIC " + Convert.ToBase64String(byteArray)); return webRequest; } } class Class1 { [STAThread] static void Main(string[] args) { F5VirtualServer.ITCMLocalLBVirtualServer bigIpVirtualServer = new F5VirtualServerWebRequest("", @""); F5VirtualServer.ITCMLocalLBVirtualServer a = new F5VirtualServer.ITCMLocalLBVirtualServer(); bigIpVirtualServer.Url = "http://10.8.0.3/iControl/iControlPortal.cgi"; try { string[] bigIpVlanWildcardAdresses; string[] virtualAddressList = bigIpVirtualServer.get_virtual_address_list(out bigIpVlanWildcardAdresses); Console.WriteLine("Virtual address list contained " + virtualAddressList.GetLength(0) + " entries."); } catch (Exception e) { Console.Write(e.ToString()); } } } }
It appears that everyone is on the same page now, so I'm happy and my application is working as expected.
Thanks to yourself and Loc for your input.
-Mark - Thanks for the tip on overriding the WebRequest Object. I'll make sure to pass this along to other users that experience the same issues.
And thanks for being understanding on the issues, it's unfortunate that they cascaded into the 4.6.2 upgrade.
I'm working on an update to the 4.6.2 SDK that will address the WSDL issue on the BIG-IP and will post when I've got it uploaded.
Lastly, glad to hear things are working for you now. Keep us up to date on what you are working on...
-Joe
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
