Showing posts with label Asynchronous Calls. Show all posts
Showing posts with label Asynchronous Calls. Show all posts

Friday, July 25, 2014

Step by step how to create Asynchronous Action Methods to improve scalability


In this tutorial we'll learn how to create Asynchronous Action Methods in Asp.Net MVC Applications. When we think of scalability, we talk about the operating system assigning a LIMITED number of threads to the incoming requests being taking care by the w3wp Asp.Net process .
If each request must perform some heavy process, or wait for some Web Service to get data from, the thread will get stuck until the arrival of the response from that Web Service .
MVC 4 - 5 has an answer for that kind of scalability issue: asynchronous action methods.
In this example we'll start an application as serial , and see the request-response using certain thread, and being stuck in wait.
Following we'll upgrade the Action Method making it asynchronous, meaning that although the user will not see any variation in terms of response speed, the web server will not collapse under thousands of frozen threads waiting for heavy services. The web page getting a response from the Asynchronous Action Method will display different threads IDs, as follows:

First think we need for this example is to create a WCF service to serve our MVC application, so open a new project and add a WCF to it:

Add an Interface:

Then add the operation  implementing the interface:

And of course define the returned Object as a Data Contract:




Now we are done with the Web Service. Build and run it, and return to your MVC app, to add a reference to the WCF service:







If the PROXY code is not automatically generated, and you get an error as follows:


That may be because you are using the IIS Express web server, and not the developer's server that ships with Visual Studio:


The IIS will identify that there is a cross-domain issue here, and avoid to call the WCF, failing at constructing the Proxy. So open the web.config and add the following code to perform cross-domain calls:


If it persists in not building the Proxy classes , as follows:


Then check that the "reuse types" in the Service Reference Configuration is UNCHECKED:





Rebuild the application and confirm that this time the Proxy classes have been built:




If everything's OK, we can code an Action method which calls the Web Service. This is a serial Action method, which begins and ends on the same thread:





The rendered web page looks as follows:



As you can see, the initial thread is the same as the final thread, and BOTH the client (browser) as the web server (our Action method) got STUCK for some seconds.
Now we'll upgrade the action method making it asynchronous:
1) Add the async directive to the action method
2) Cast the ActionResult to Task<ActionResult>
3) Call the asynchronous version of the WCF service method ( ....... Async() )
4) Wait for the WCF response using the "await" operator:



I also added an await Task.Delay(3000) to make the action method more heavy and slow to return a response. Now you can see that the browser awaits the same time for a web server response, but the thread  does not get stuck since it is resumed by another thread created when the WCF response triggers the callback , which is managed on a NEW THREAD:




If you liked the Twitter Bootstrap ScrollSpy used in the web page markup at this tutorial, you can copy it from this tutorial.

That's all!!  In this tutorial we've learned  how to create Asynchronous Action Methods in Asp.Net MVC Controllers.
Happy programming.....
        By Carmel Schvartzman
כתב: כרמל שוורצמן







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
כתב: כרמל שוורצמן


Tuesday, July 1, 2014

Step by step how to send a cross-domain Ajax request

        By Carmel Schvartzman


In this tutorial we'll learn how to send a cross-domain Ajax HTTP request using javascript jQuery methods. We'll use the $.ajax() method to render just a sample XML response , fixing the "No 'Access-Control-Allow-Origin' header is present on the requested resource" error.

Let's say you have a web page which sends HTTP GET or HTTP POST requests to a web service (WCF endpoint or OData service) to load the data :





Everything works fine , provided that BOTH the client and the web services are in the SAME DOMAIN. The problem will arouse while the client and the server are hosted in DIFFERENT DOMAINS :





We got an  "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, and there are "provisional" headers displayed.
Why? Because in the case of AJAX cross-domain requests, the browser sends some kind of "PRE-REQUEST" to  the web server, of the type of HTTP OPTIONS verb, informing that a CROSS-DOMAIN violation is being produced. Is then up to the web server to send or not a response to the web client.
That's because cross-domain HTTP requests started from scripts are subject to security restrictions. The 'CORS' (Cross Origin Resource Sharing) policy,  prevents access to methods and properties across DOMAINS, that means,  pages on different  web sites will not successfully retrieve data from some other domain, subdomain, or even internet protocol. For example, some resource loaded from  the domain http://AAAdomain.com)   makes a HTTP request for a resource on OTHER domain such as  http://BBBdomain.com . A web application can only make HTTP requests via AJAX to the domain to which it belongs, and not to other domains.
You can access to in-deep information about CORS policy in this web site.
To solve the  problem, we'll simply set the "Access-Control-Allow-Origin" header on our web server, setting it to "*" , in order to accept cross-domain AJAX HTTP requests from different domains.

Our Ajax request will be as follows:

 $.ajax(              {  

    crossDomain: true,

                url: url,
                type: "GET",
                contentType: "text/plain", 
                dataType: "xml",
                data: "",
                success: function (data)
                {                   
                    $(data).find('entry').each(function (index) {                         
                     
                        var id = $(this).find('BlogID').text();  
                        var title = $(this).find('Title').text();  
                        var text = $(this).find('Text').text();
                        var img = $(this).find('MainPicture').text();                        
                       
                    });                   
                                   },
                error: function (res) {
                    alert(res.status);
                }            });





And inside the <system.webServer> element at the web.config of the web server we'll set the headers to "*" :







<!--<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>  



That's all we must get done, to enable cross-domain AJAX requests.

In this tutorial we've learned how to send a cross-domain Ajax request using javascript jQuery methods,  fixing the "No 'Access-Control-Allow-Origin' header is present on the requested resource" error.

That's all!! 
Happy programming.....

כתב: כרמל שוורצמן










Wednesday, May 14, 2014

Step By Step How to make Asynchronous calls to the Google Maps API in MVC 4

        By Carmel Schvartzman

In this tutorial we'll learn how to make Asynchronous calls to the Google Maps API in MVC 4. We'll build an application which loads a Google Map according to the user's input coordinates, in an asynchronous way. 
We want to load the Maps API code when the user press a button, sending an asynchronous call to the API. To do so, we inject a <script> tag in response to that event, additionally instructing the API to delay execution of our application until the API code is loaded. We'll do so using the "callback" parameter, with the name of the function to execute upon loading the API.In order to do all that, we must have a Google Maps Developer Key. I'll lead you through the process of getting that Key from Google's Developer Center.
The Google Maps API application must load the Maps API using an API developer key. Using an API key enables the developer to test the application's Maps API.
The Key is free of charge, but it limits you to 25,000 requests per day, and also you're not allowed to use the Developer Key on any comercial purposes.

We'll want to create a Google Maps API in MVC 4 , showing as follows:





To get your personal Developer Key, search "google maps API key":


You'll browse to the developers.google.com site:




There you can click the link "Learn how to use an APIs console key":


Alternatively, you can directly enter the Google Maps API:




Selecting the "WEB" option, you get to the Web API:


Choose Javascript API v3, and then "Obtaining an API Key":


There you get a walktrough about obtaining the Key:


To see the differences between the FREE option to the COMERCIAL, take a look here:


Whether if you browse to the new Developer's Console:




...and choose the "APIs" from the Menu, or you enter the old Console...




...and select the "Services" from the Menu, look for the API called "GOOGLE MAPS JAVASCRIPT API v3", and ENABLE it, to obtain your Key:






After you log in with your Google ID, you get a Public API Access Key:


Save the API Key to a safe place. Now you have your Developer's Key.

We're ready to create an HTML file to use the Google Maps API. First add the DOCTYPE directive and the CSS we'll be using:

<!DOCTYPE html>
<html>
  <head>
    <title>Asynchronous Google Map</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <style>
      html { width:100%;height: 100%; }
      body { font:900 12px Georgia;color:#fff;background:#c67f1c;width:90%;height:90%;margin:5px 5px 5px 5px; }
      #map { width:70%;height: 97%; }
    </style>
Next, let's add the UI to get the coordinates from the user. I hard-coded some coordinates to get my own town in Argentina, Concepcion del Uruguay. You type want you like:

</head>
  <body>
     <div>
    Type the latitude : &nbsp; <input id="latitude" value="-32.484" /><br />
Type the longitude : <input id="longitude" value="-58.231" /><br />
        <input type="button" value="Asynchronously Load Google Map" onclick="fnLoadMap()"/>
</div>
    <div id="map"></div>
  </body>
</html>

Finally, we code the javascript function to load the Google Map when the user press the button. In order to do that, we'll take a look at the API Reference of the API version 3:



We'll load the Google Map calling the API function "Map", with a "MapOptions" argument, including the "center" property, which specifies the coordinates of the map:




...and including also the "zoom" we want to display the map:

, including also the javascript for the API, with the Developer Key that you got from Google(replace the "HERE_YOUR_DEV_KEY" with your personal Key):


<script>
function initialize() {
  var lat = document.getElementById("latitude").value;
  var long = document.getElementById("longitude").value;
  var mapOptions = {
    zoom: 15,
    center: new google.maps.LatLng(lat,long)  
  };
  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);
  document.getElementById("map").innerHTML = map;
}
function fnLoadMap() {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'https://maps.googleapis.com/maps/api/js?key=HERE_YOUR_DEV_KEY&sensor=true&' +
      'callback=initialize';
  document.body.appendChild(script);
}

</script>

The final code of the function will be as the following:


function fnLoadMap() {

var lat = document.getElementById("latitude").value;
        var long = document.getElementById("longitude").value;
        var mapOptions = {

          center: new google.maps.LatLng(lat,long),
          zoom: 15
        };
        var map = new google.maps.Map(document.getElementById("map"),
            mapOptions);
document.getElementById("map").innerHTML = map;
      }

The HTML file should look as follows:



Open the HTML in some browser, to see this UI:


Change the coordinates and press the button:





That's all!! 


In this tutorial we've learned how to make Asynchronous calls to the Google Maps API in MVC 4. We built an application which loads a Google Map according to the user's input coordinates.   

Happy programming.....

כתב: כרמל שוורצמן