0

I am trying to catch WebException from asynchronous HttpWebRequest to read soap:fault from api. But it throws AggregateException. Is there a way to catch WebException for Async HttpWebRequest ?

public async Task<XDocument> GetXmlSoapResponseAsync(string soapRequestURL, string xmlData)
    {
      try
      {
        //create xml doc
        XmlDocument doc = new XmlDocument();

        //load xml document frtom xmlData
        doc.LoadXml(xmlData);
        //creta web request
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(soapRequestURL);
        req.ContentType = "text/xml";
        req.Accept = "text/xml";
        req.Method = "POST";

        //GetRequestStream from req
        Stream stm = req.GetRequestStream();
        doc.Save(stm);
        stm.Close();

        Task<WebResponse> task = Task.Factory.FromAsync(
        req.BeginGetResponse,
        asyncResult => req.EndGetResponse(asyncResult),
        (object)null);

        var response = task.Result;
        return await task.ContinueWith(t => ReadStreamFromResponse(response,stm, soapRequestURL,xmlData));
      }
      catch (WebException webException)
      {
        LogWebException(webException, soapRequestURL, xmlData);

        return null;
      }

    }
dcastro
  • 66,540
  • 21
  • 145
  • 155
sanjeev
  • 1,407
  • 2
  • 18
  • 30

1 Answers1

3

Change this

var response = task.Result;

to this

var response = await task;

await returns the result of the task or unwraps the AggregateException, if any.


Also, .Result blocks the current thread until the result is available, and that's probably not what you want, otherwise you'd just be using the blocking GetResponse, instead of the async BeginGetResponse and EndGetResponse.

Also, you don't even need those two methods. There's a better one - GetResponseAsync

Use this:

var response = await req.GetResponseAsync();

Instead of this:

Task<WebResponse> task = Task.Factory.FromAsync(
req.BeginGetResponse,
asyncResult => req.EndGetResponse(asyncResult),
(object)null);

var response = task.Result;
dcastro
  • 66,540
  • 21
  • 145
  • 155
  • thanks for quick perfect answer and optimizing my codes with await req.GetResponseAsync();. I am new to this async thing and I have to read more to understand it properly. Thank you so much! – sanjeev Mar 01 '14 at 22:50
  • 1
    @sanjeev No problem. The `BeginXX` and `EndXX` pair of methods are a part of the [APM - Asynchronous Programming Model](http://msdn.microsoft.com/en-us/library/ms228963(v=vs.110).aspx) and they were really useful before .NET 4.5. Nowadays, with the introduction of async/await, in *most* situations, you're better of using the `XXAsync` counterpart. – dcastro Mar 01 '14 at 22:55
  • @sanjeev Also, if you ever need to use an API that has the `Begin`/`End` pair of methods, but doesn't have an `XXAsync` method - then you should use `Task.Factory.FromAsync` to create a task and await it, like you were doing ;) That's a workaround for older APIs. – dcastro Mar 01 '14 at 23:00
  • Ah great to know about this workaround. I wasn't aware of that. Thanks. – sanjeev Mar 01 '14 at 23:06
  • Shame `await` isn't available in VS 2010. – ForeverWintr Mar 05 '14 at 19:46
  • @ForeverWintr `await` isn't a visual studio feature, it's a C# feature. Which version are you using? – dcastro Mar 05 '14 at 20:05
  • Really? [This msdn article](http://msdn.microsoft.com/en-us/library/hh156570(v=vs.110).aspx) suggested to me that it was. `"The Async and Await keywords were introduced in Visual Studio 2012. For information about new features in that version, see What's New in Visual Studio 2012."` I'm using VB.net (10) actually. – ForeverWintr Mar 05 '14 at 22:20
  • @ForeverWintr Well, that was a really poor choice of words. Visual Studio is an IDE. What they probably meant was - You need the C# 5.0 compiler - and the Visual Studio 2012 installer comes with that compiler. Which version of .NET are you targeting though? You can make it work with VS2012 + .NET 4 by using the `Microsoft.Bcl.Async` package, see this: [Using async-await on .net 4](http://stackoverflow.com/questions/9110472/using-async-await-on-net-4) – dcastro Mar 05 '14 at 22:26
  • Ah. That makes sense. The joys of Microsoft documentation. I am targeting .NET 4.0 (because I need to support old versions of MS Office). I'll look into `Microsoft.Bcl.Async`. Thanks for the clarification! – ForeverWintr Mar 05 '14 at 22:35