Sunday, July 20, 2014

Step by step how to call a WCF Service Endpoint from both Serial and Asynchromous MVC Controller

   In this tutorial we'll learn how to call a WCF Service from both asynchronous and serial Controllers in Asp.Net MVC. We'll first build a WCF Service, and call it from a Proxy at an MVC Application. Then we'll code an Asynchronous Controller and call the same WCF service but using the async methods automatically created inside the Proxy by Visual Studio.
That way we'll compare the async and serial approaches of calling a WCF service from MVC:

Let's first of all create the WCF as an external project :

Create an Operation contract Interface as follows:
 Then implement that Interface in a class as follows:
 And define the DataContract which is contained in the WCF response:

At the MVC application, add a Service Reference:

Enter the WCF service URL or press "Discovery" :

You'll discover the only method that we declared at the WCF service:

Press OK. If you get an error as this:

That means that your MVC is running at the IIS Express or at the IIS installed at your machine, instead of running on the Developer Server that comes with Visual Studio. The difference is, the former will notice that there are 2 different applications (WCF + MVC) and hence 2 different domains, and will avoid cross-domain calls:

In order to allow cross-domain, add the following code to your web.config file at the WCF project:

<system.webServer><httpProtocol>      <!--THIS IS FOR CORS POLICY-->      <customHeaders>        <add name="Access-Control-Allow-Origin" value="*" />        <add name="Access-Control-Allow-Headers" value="Content-Type" />        <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />      </customHeaders>    </httpProtocol>  </system.webServer>

After that, may be you don't have an error but you see that the Proxy has not been created at the MVC application, as follows ( you can look for the Proxy classes at the Service References folder of your project: there are supposed to be .cs files containing the methods and classes created to the dialog between the MVC and the WCF service):

Then open the WCF reference at your MVC , and select "Configure" :

There UNCHECK the "Reuse types in referenced assemplies" box:

You'll see immediatly that the Proxy has been built:

Take a look at the Proxy and , specially, at the "async" methods created:

Now add some Controller calling the WCF through that Proxy, and its respective View:

As you can see, both the request and response has been handled by the same thread:

That means, the thread has been blocked waiting for the WCF service to answer the request from the MVC Controller. In other words, if there are 1,000 users in certain moment viewing this MVC web page, the web server will have at least 1,000 threads stuck and consuming its resources while waiting for WCF.
To avoid that situation, let's convert our Controller to an ASYNCHRONOUS method, meaning that no thread will get stuck waiting now:

The only thing you have to add to your Controller is:
1) an "async" expression and a Task<ActionResult> return object,
2) the "await" expression in order to automatically declare this Controller as the callback function to be called back by the:
3) the GetMessageASYNC Proxy method .
That's all the changes. (i added also an "await Task.Delay(3000)" just to make the waiting more heavy, for the test sake). Now you can see that the thread which got the request IS DIFFERENT from the thread corresponding to the callback function which was called by the Proxy when the WCF service sent its response:

That's all!!  In this tutorial we've learned how to call a WCF Service from both asynchronous and serial Controllers in Asp.Net MVC.
Happy programming.....
      By Carmel Schvartzman
כתב: כרמל שוורצמן