I have been recently given the task to be in charge of a project using the AdWords API.
The AdWords API actually consists of a serie of Web Services which let you access to your AdWord account through an API instead of a normal user interface. The documentation regarding the Web Services can be found at: https://developers.google.com/adwords/api/docs/
To access the AdWords API using a .Net client, there is a .Net solution with pre-generated Web Service proxies that you can find at http://code.google.com/p/google-api-adwords-dotnet/.
The documentation regarding the .Net client is pretty scarce but there is an AdWords API forum where you can find solutions to your problems and also post your own questions.
Please note that the problem I describe hereunder applies to the latest .Net client available at time of writing (mid-January). This blog post applies only if you encounter the same problem with your version of the .Net client code. Would a future release not show the problem, no fix will be needed.
The only problem I have had so far with the proxy classes is that they constantly threw me an error message saying that “The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.”
This problem is similar to what I have previously encountered in BizTalk projects when .Net HTTP requests access a Web Server which ignores the keepAlive instruction. This is often the case with Apache servers (or should I say their administrators? – I am not sure if this is a setting they can change). Anyway, for people interested, I have posted more details about the problem in a previous post: BizTalk HTTP Adapter and Apache Keep-Alive issue.
So, the first thing I had to do to fix the issue is to modify every Web Service proxy classes so that the HTTP request used to make the Web Service call has its KeepAlive setting set to false.
All Web Service proxy classes that are using SOAP extends from the SoapHttpClientProtocol class. Web methods belonging to the WebService are called using the Invoke() method. Nevertheless, we, as client programmers, do not call the Invoke method directly, it is instead the proxy class which wraps the Invoke() call into a method matching the WebService method signature. For example, the ReportService proxy class delivered in the AdWords API .Net client has a method validateReportJob() which matches the WebService method defined on the server and which encapsulates the call to the Invoke() method:
public void validateReportJob(ReportJob job)
{
this.Invoke(“validateReportJob”, new object[] {job});
}
The SoapHttpClientProtocol.Invoke() method is implemented using the protected method GetWebRequest () which creates an instance of a WebRequest object that the Invoke() method uses to establish an HTTP connection with the web server.
With this in mind, all we have to do is to override the GetWebRequest() method in our ReportService proxy class so that we can intercept the WebRequest object created and modify the properties we want to customize.
Note that the WebRequest class is in fact an abstract classs and that the actual object returned at runtime is a class implementing the protocol used. In cases of Web Services and everything that runs over HTTP, it is the HttpWebRequest class.
So in our case, I have added the following code in the ReportService proxy class:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
webRequest.KeepAlive = false; //set the HTTP Header to not keep connections alive between requests
webRequest.Timeout = 1200000; // The length of time, in milliseconds, until the request times out (20 minutes here)
return webRequest;
}
With this piece of code in each of the Web Service classe proxies, “the connection closed” exception is not thrown anymore as both the .Net client and the Apache server that runs on http://adwords.google.com have the same KeepAlive setting.
I am facing the same issue with some vendor web services. I searched and came across the smiliar solution that you have proposed. Have you been able to find a solution that does not involve changing the wrapper class created by VS 2003 IDE? Thank you.
Hi,
This is the only solution I tried.
In .Net 2.0 and above you could use partial class. You would nevertheless still need to change the code of the wrapper class to add the “partial” modifier in the class declaration.
The easiest solution I have on the top of my head for .Net 1.1 is that you could create a class that derives from the wrapper class and overrides the GetWebRequest() method there.
Your client code will then need to instantiate that derived class instead of directly instantiating the wrapper class.
There might be another way to achieve the same goal by using Soap Extensions. They are normally used to manipulate the SOAP message and I do not think that they can be used to manipulate the HTTPRequest object. Nevertheless, as I am not 100% sure about that I mention it to you in case you would look for alternatives to the previous solution.
HTH,
Francois