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.