Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to throw an exception from callback in WCF Async using IAsyncResult

I am using WCF Async calls in my project and i am using Client side asynchronous methods. I have a scenario like below -

  //Code in Business Layer and this method is called from Web layer 
    private void GetGeneralNews()
    {
        client.BeginGetGeneralNewsFeed(GeneralNewsCallback, null);
    }

    //Call Back Method
    private static void GeneralNewsCallback(IAsyncResult asyncResult)
    {
       string response = string.Empty;

       try
       {
          response = client.EndGetGeneralNewsFeed(asyncResult);
       }
       catch(Exception ex)
       {
          throw ex; // Here is the problem. It does not throw the exception to the web layer instead it will suppress the   error.
       }
    }

So as shown in the above code snippet it does not throw the exception from business layer to web layer as it will be suppressed here in business layer itself.

I checked in some of the blogs and sites they are suggesting to go for async and await approach, as i have .NET 4.0 framework and i am seeing "Generate task-based Operations" option disabled. So if there are any options using "IAsyncResult" (Begin & End in client side) please let me know. If there are any other approaches also welcome.

Kindly someone help me.

Thanks.

like image 445
Abhijith Nayak Avatar asked Apr 06 '15 17:04

Abhijith Nayak


1 Answers

Here is a sample app which shows that WCF doesn't swallow the exception. If you don't receive the exception, it must be swallowed by your server side code.

using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using WcfQ.QServiceReference;

namespace WcfQ
{
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class QService : IQService
{
    public void Foo()
    {
        throw new ApplicationException("Please catch this");
    }
}

[ServiceContract]
public interface IQService
{
    [OperationContract]
    void Foo();
}

class Program
{
    static private QServiceClient client;

    static void Main(string[] args)
    {
        ServiceHost host = new ServiceHost(typeof(QService), new Uri("http://localhost:20001/q"));
        AddWsdlSupport(host);
        host.AddServiceEndpoint(typeof (IQService), new WSHttpBinding(SecurityMode.None), "");
        host.Open();

        client = new QServiceClient();
        client.BeginFoo(FooCallback, null);
        Console.WriteLine("ready");
        Console.ReadKey();
    }

    private static void FooCallback(IAsyncResult asyncResult)
    {
        try
        {
            client.EndFoo(asyncResult);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Got the exception: " + ex.Message);
        }
    }

    static void AddWsdlSupport(ServiceHost svcHost)
    {
        ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
        // If not, add one
        if (smb == null)
            smb = new ServiceMetadataBehavior();
        smb.HttpGetEnabled = true;
        smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
        svcHost.Description.Behaviors.Add(smb);
        // Add MEX endpoint
        svcHost.AddServiceEndpoint(
          ServiceMetadataBehavior.MexContractName,
          MetadataExchangeBindings.CreateMexHttpBinding(),
          "mex"
        );

    }
}

}

Here is the output of this program:

ready 
Got the exception: Please catch this
like image 184
Alon Catz Avatar answered Nov 09 '22 04:11

Alon Catz