Thursday, June 23, 2011

Calling Cross Domain WCF service using Jquery/Javascript

Shout it kick it on DotNetKicks.com
This post is about to call the cross domain WCF service from you page i.e Calling WCF service hosted on one domain and calling the service form jquery/javascript of page which is hosted on some other domain.
But before we start its better to get understand about the format of the data get exchange from one server to other server.

JSONP
Ajax allows to get data in the background without interfering with the display. Ajax call done by using XMLHttpRequest object, which is allow the client side javascript code to make HTTP connections.

But Ajax call does not allow to get data from cross-domain because of restrictions imposed by the browser. Security error get issued when requesting data from a other domain. one way to avoid security errors is to control remote server where data resides and every request goes to the same domain, that rise question what's the fun if data come form own server only? What to do if data require to get form the other server?

There is one way to come out form this limitation is to insert a dynamic script element in the Web page, one whose source is pointing to the service URL in the other domain and gets the data in the script itself. When the script loads, it executes. It works because the same-origin policy doesn't prevent dynamic script insertions and treats the scripts as if they were loaded from the domain that provided the Web page. But if this script tries to load a document from yet another domain, it will fail. Fortunately, you can improve this technique by adding JavaScript Object Notation (JSON) to the mix.

JSONP or "JSON with padding" is a complement to the base JSON data format, a pattern of usage that allows a page to request data from a server in a different domain. As a solution to this problem, JSONP is an alternative to a more recent method called Cross-Origin Resource Sharing.

Under the same origin policy, a web page served from server1.example.com cannot normally connect to or communicate with a server other than server1.example.com. An exception is the HTML <script> element. Taking advantage of the open policy for <script> elements, some pages use them to retrieve Javascript code that operates on dynamically-generated JSON-formatted data from other origins. This usage pattern is known as JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. They are evaluated by the JavaScript interpreter, not parsed by a JSON parser.

Calling Cross Domain WCF service
Now in following discuss I am going to show you how easily you can call the WCF service hosted on the other domain from the page hosted on the other domain.

Following is list of article you should look first before moving further

Create, Host(Self Hosting, IIS hosting) and Consume WCF servcie
Steps to Call WCF Service using jQuery

To start first create new solution and Add new Project which is WCF service and follow below steps

Step 1
In new release of .net 4.0 the WCF developer team added support for JSONP. There is a new property added which enable to call WCF service from other domain by setting its true.
CrossDomainScriptAccessEnabled - Gets or sets a value that determines if cross domain script access is enabled.

Change your WCF servcie config file as below


  
    
    
  
  
    
  
  
    
    
      
        
      
    
  

As you can see in above config code I have set crossdomainscriptaccessenabled to true and aspnetcompatibilityenabled is to true so that the WCF service works as a normal ASMX service and supports all existing ASP.NET features.
Step 2

SVC file of the service should be like as below

<%@ ServiceHost Language="C#" Debug="true" 
Service="WcfService1.Service1" 
CodeBehind="Service1.svc.cs"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"  %> 
Don't forget to add Factory attribute because it cause error if you remove it. Following are the reason to add Factory attribute
1. Service host factory is the mechanism by which we can create the instances of service host dynamically as the request comes in.
2. This is useful when we need to implement the event handlers for opening and closing the service.
3. WCF provides ServiceFactory class for this purpose.
Step 3

CS file for the WCF file is

using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace WcfService1
{
    
    [DataContract]
    public class Customer
    {
        [DataMember]
        public string Name;

        [DataMember]
        public string Address;
    }


    [ServiceContract(Namespace = "JsonpAjaxService")]
    [AspNetCompatibilityRequirements(RequirementsMode =   AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1
    {
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        public Customer GetCustomer()
        {
            return new Customer() { Name = "Pranay", Address = "1 Ahmedabad" };
        }
    }

}
As you can see in the above code I have created Service class which is service contract which servs data and Customer class is DataContract which get served as respose.
In the service class GetCustomer method service data in Json format.

Once the WCF service created to move further Add new project >> Asp.Net service. So that both the WCF service and website runs on tow different like both hosted on different domain.

There is two solution to call the Cross Domain WCF service.

Solution 1 : Call WCF service by using JQuery
Jquery already have support to handle the jsonp. Jquery library provided function ajax and getJson which can allow to call the WCF service which send jsonp data in response.

CallService - Generic function is used to call the WCF servcie, which get called by other javascript function to get and display data

var Type;
        var Url;
        var Data;
        var ContentType;
        var DataType;
        var ProcessData;
        var method;
        //Generic function to call WCF  Service
        function CallService() {
            $.ajax({
                type: Type, //GET or POST or PUT or DELETE verb
                url: Url, // Location of the service
                data: Data, //Data sent to server
                contentType: ContentType, // content type sent to server
                dataType: DataType, //Expected data format from server
                processdata: ProcessData, //True or False
                success: function (msg) {//On Successfull service call
                    ServiceSucceeded(msg);
                },
                error: ServiceFailed// When Service call fails
            });
        }
ServiceFailed - is get called when call to service fail.

function ServiceFailed(xhr) {
            alert(xhr.responseText);
            if (xhr.responseText) {
                var err = xhr.responseText;
                if (err)
                    error(err);
                else
                    error({ Message: "Unknown server error." })
            }
            return;
        }
ServiceSucceeded - is get called when the service successfully return response. As you can see in the function I am checking DataType is jsonp which is just to demonstrate that service is returning jsonp data.

function ServiceSucceeded(result) {
            if (DataType == "jsonp") {
                
                    resultObject = result.GetEmployeeResult;
                    var string = result.Name + " \n " + result.Address ;
                    alert(string); 
            }
        }
GetEmployee - is function that get called to request data from WCF service hosted on other domain. As you can see in code DataType value is get set to jsonp.

function GetEmployee() {
            var uesrid = "1";
            Type = "GET";
            Url = "http://localhost:52136/Service1.svc/GetCustomer"; 
            DataType = "jsonp"; ProcessData = false;
            method = "GetCustomer";
            CallService();
        }

        $(document).ready(
         function () {
            
             GetEmployee();
         }
);
Solution 2 : Call WCF Service by Javascript

To call the service using javascript make use of ScriptManager


        
            
        
    
in above code I set the servicereferance to the WCF service hosted on other domain.
makeCall - is function that get called to request data from WCF service hosted on other domain.

function makeCall() {
                      var proxy = new JsonpAjaxService.Service1();
                     proxy.set_enableJsonp(true);
                     proxy.GetCustomer(onSuccess, onFail, null);
                 }
onSuccess - is called when the result from the service call is received and display data.

function onSuccess(result) {
                     alert( result.Name + " " +result.Address);
                 }
onFail - is called if the service call fails

function onFail(){
                     alert("Error");
                 }
Summary
So after the addition to the special property by the WCF team its quite easy to call cross domain WCF service.
References
JSONP - WIKI
Cross-domain communications with JSONP


Saturday, June 18, 2011

Dictionary Object (ContainsKey Vs. TryGetValue)

Shout it kick it on DotNetKicks.com
Here I am going to discuss about two important method of the Dictionary<tkey, tvalue> class to play with the data of the Dictionary.

Dictionary<tkey, tvalue> class allows us to create key , vlaue pair collection. The Dictionary<tkey, tvalue> generic class maps of keys to a set of values. Dictionary consists of a value and its associated key. Value can be retived by using its key is very fast, close to O(1), because the Dictionary>tkey, tvalue< class is implemented as a hash table.
Now to understand what I am going to discuss in this post

I am creating Dictionary object
Dictionary<string, string> dic = new Dictionary<string, string>();
Dictionary Class has method Add which allows to add the key, value pair data in the dictionary object
dic.Add("Pranay",  "Rana");
dic.Add("Hemang", "Vyas");
dic.Add("Krunal", "Mevada");
dic.Add("Hanika",  "Arora");
Now after adding the key,value pair it's need to take out the value out of the dictionary object and use that values because after all dictionary object used to store the values and to get it back.
To take value back from the Dictionary object , it require to make use of key
Type value = dic[key];
But the problem with this is it throws KeyNotFoundException if the key is not exists in dictionary.

ContainsKey 
Dictionary class provide methods ContainsKey which used to check where the key is present or not.
Signature bool ContainsKey(<TKey> key)
So most of the developer use this method to check value and if the value is exits they get the value back.
if (dic.ContainsKey(key))
{
     string result = dic[key];
     Console.WriteLine(result);
}
TryGetValue
But Dictionary object provide one more method TryGetValue which check key is present in dictionary present or not and if present return value by out parameter.
Signature bool TryGetValue(<TKey> key,out <TValue> val)
By using the method code is like
if (dic.TryGetValue(key, out val))
{
   Console.WriteLine(val);
}
By using two method one can avoid throwing the KeyNotFoundException.

But the question is What is the difference between two approach related to ContainsKey and TryGetValue ?
The first diffrence is ContainsKey approach only checks weather key is present or not and than get the value , but the TryGetValue not only check key is present or not but also get the value for that key.
So the TryGetValue make code easy and simple.

The second difference is TryGetValue approach is faster than ContainsKey.
To check out I wrote following code and executed on my machine.
Note : Stopwatch class exists in System.Diagnostics Namespace to get the time require to execute the line of code.
Dictionary<string, string> dic = new Dictionary<string, string>();
      dic.Add("Pranay",  "Rana");
      dic.Add("Hemang", "Vyas");
      dic.Add("Krunal", "Mevada");
      dic.Add("Hanika",  "Arora");

      //First method ContainsKey
      Stopwatch st = new Stopwatch();
      st.Start();
      foreach (string key in dic.Keys)
      {
          if (dic.ContainsKey(key))
          {
             string result = dic[key];
             Console.WriteLine(result);
          }
      }
      st.Stop();
      TimeSpan ts = st.Elapsed;
      Console.WriteLine("RunTime " + ts.Milliseconds);


      //Second method TryGetValue
      string val = string.Empty;
      Stopwatch st1 = new Stopwatch();
      st1.Start();
      foreach (string key in dic.Keys)
      {
          if (dic.TryGetValue(key, out val))
          {
              Console.WriteLine(val);
          }
      }
      st1.Stop();
      ts = st1.Elapsed;
      Console.WriteLine("RunTime " + ts.Milliseconds);

After the test I got following output
As you can see in the image the first one take 4 millisecond to get the values and the later one take 1 millisecond.

Note :
TryGetValue approach is faster than ContainsKey approach but only when you want to check the key in collection and also want to get the value associated with it. If you only want to check the key is present or not use ContainsKey only.

Wednesday, June 15, 2011

Help yourself in Debugging by using Call Stack and Immediate Window

Shout it kick it on DotNetKicks.com
In this post I am going to show you the two important window of the Visual Studio which is useful when you debugging the project and to get the result on the fly during debug.

Call Stack Window
Most of the developer get confuse when they are debugging application "From which function call came from up to my debug point", this happens when they are working the code design by some one else or debugging code of the dll.

Following is one common scenario which I notice number of time developer does.
In the three tier application developers always put the break point in presentation layer when the break point get hit they always check the data and the do wonder that which business layer method called >> database layer method get called by presentation layer to get this data.

The Solution is Call Stack Window which is part of the Visual Studio. Shortcut for it is
Ctrl + Alt + C or go to menu Debug >> Windows >> Call Stack









As you can see the image with the help of the Call Stack Window you will get information about the method get called, what is parameter value, line no of the method in file, is it external call or internal, programming language in which method written.

Immediate Window
It always happen that in middle of debugging you want to execute some set of statement or some set of function or want to check the value of the variable. But as beginner you don't know how to do it at time of debug ?

You can open up the Immediate window by shortcut Ctrl + Alt + I or go to menu Debug >> Windows >> Immediate Window






Immediate window has intelligence support as we have in the Coding window of the Visual Studio so that you can easily make use of the function, which makes you task easy.

Sunday, June 12, 2011

Ordering data in LINQ Queries by more than one column

Shout it kick it on DotNetKicks.com
In this post I am going to show how to do ordering when you require to order data by using the multiple columns.

By using .Orderby(x=>x.Columnname) in the LINQ query we can easily order data of the source collection. So most of new developer make use of the same function two time .Orderby(x=>x.Columnname).Orderby(x=>x.Columnname) and thinks that will do the ordering on the multiple columns.
IEnumerable<Employee> emp = dc.Employees
                                 .OrderBy(x => x.Name)
                                 .OrderBy(x => x.Desc); 

But its always does the order by the column you specified in the last OrderBy() method.

Following is two solution to achieve
Solution 1:
Always make use of ThenBy() after OrderBy() because  OrderBy() returns an IOrderedEnumerable which then exposes the Methods: ThenBy() and ThenByDescending(). This means that we can OrderBy on multiple Fields by chaining the OrderBy() and ThenBy() together.
IEnumerable<Employee> emp = dc.Employees
                                  .ThenBy(x =< x.Name)
                                  .OrderBy(x => x.Desc);

Solution 2:
If you don't want to go for the Lamda expression where you can easily achieve the multiple ordering
var emp = from e in dc.Employees
          orderby e.Name, e.Desc
          select e;
As you can see in above statement after order by you can add the multiple columns and do the ordering on multiple columns.

Thursday, June 9, 2011

IQueryable Vs. IEnumerable in terms of LINQ to SQL queries

Shout it kick it on DotNetKicks.com
Few days ago I am working on my project which is having Linq to Sql as database layer. I got requirement to get the first of all employee who's designation starts with "soft".

I get fired below query and got the result in IEnumerable varible
IEnumerable<employee> emp = 
         dc.Employees.Where(x => x.Desc.StartsWith("soft"));
emp = emp.Take(1);
But later on I found there it’s taking too much time to get the count.

So to try something else I use IQueryable to store the result and to get the count.
IQueryable<employee> emplist = 
         dc.Employees.Where(x => x.Desc.StartsWith("soft"));
emplist = emplist.Take(1);

After using IQueryable I found I get result faster than previous one.

So to find out this I used SQL Profile to find out the SQL Query fired by the code.

First block of code  fire following query i.e which use IEnumrable to store output of the LINQ query
SELECT [t0].[Id], [t0].[Name], [t0].[Address], [t0].[Desc] AS [Desc]
FROM [dbo].[Employee] AS [t0]
WHERE [t0].[Desc] LIKE @p0
Second block of code  fire following query i.e which use IQuerable to store output of the LINQ query
SELECT TOP (1) [t0].[Id], [t0].[Name], [t0].[Address], [t0].[Desc] AS [Desc]
FROM [dbo].[Employee] AS [t0]
WHERE [t0].[Desc] LIKE @p0

Major difference between both query is First one doesn't contain the TOP clause to get the first record but second one make use of the TOP to get the first record.

When I explore further I fond following difference between both ?

The major difference is that IEnumerable will enumerate all elements, while IQueryable will enumerate elements, or even do other things, based on a query. In case of IQueryable Linq Query get used by IQueryProvider  which must interpret or compiled in order to get the result.
i.e Extension methods defined for IQueryable take Expression objects instead of Func objects (which is what IEnumerable uses)., meaning the delegate it receives is an expression tree instead of a method to invoke.

IEnumerable is great for working with in-memory collections, but IQueryable allows for a remote data source, like a database or web service.