Authentication on WCF Data Service or OData: Windows Authentication Part#1

In this article, I am going to show how to enable windows authentication on WCF Data Service.

Follow the below steps

Step 1

Create WCF Data Service.

Read below how to create WCF Data Service and introduction to OData.

http://dhananjaykumar.net/2010/06/13/introduction-to-wcf-data-service-and-odata/

While creating data model to be exposed as WCF Data Service, we need to take care of only one thing that Data model should be created as SQL Login

So while creating data connection for data model connect to data base through SQL Login.

Step 2

Host WCF Data Service in IIS. WCF Data Service can be hosted in exactly the same way a WCF Service can be hosted.

Read below how to host WCF 4.0 service in IIS 7.5

http://dhananjaykumar.net/2010/09/07/walkthrough-on-creating-wcf-4-0-service-and-hosting-in-iis-7-5/

Step 3

Now we need to configure WCF Service hosted in IIS for Windows authentication.

Here I have hosted WCF Data Service in WcfDataService IIS web site.

Select WcfDataService and in IIS category you can see Authentication tab.

On clicking on Authentication tab, you can see various authentication options.

Enable Windows authentication and disable all other authentication

To enable or disable a particular option just click on that and at left top you can see the option to toggle

Now by completing this step you have enabled the Windows authentication on WCF Data Service hosted in IIS.

Passing credential from .Net Client

If client windows domain is having access to server then

If client is not running in windows domain which is having access to server then credential we need to pass the as below,

So to fetch all the records

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            NorthwindEntities1 entity = new NorthwindEntities1
                                       (new Uri("http://localhost:7890/wcfdataservice1.svc/"));
            entity.Credentials = System.Net.CredentialCache.DefaultCredentials;
            entity.Credentials = new System.Net.NetworkCredential("UserName", "Password", "Domian");
            try
            {

                var result = from r in entity.Products select r;
                foreach (var r in result)
                {
                    Console.WriteLine(r.ProductName);
                }
            }
            catch (DataServiceQueryException ex)
            {
                Console.WriteLine(ex.StackTrace);
            }




        }


    }
}



In above article we saw how to enable Windows authentication on WCF Data Service and then how to consume from .Net client. In next article we will see how to consume Windows authenticated WCF Data Service from SilverLight client.

IgnoreDataMember attribute in WCF POCO Serialization

POCO stands for PLAIN OLD CLR OBJECT.

If  in WCF we are using

1. Complex Data type for example custom class

2. And not attributing this custom class as DataContract and properties of the class as DataMember

3. If we want to expose the below custom class to client and not using DataContractSeraliazer then all public properties will be automatically serialized

public class MyCustomData
{
    public string Name { get; set; }
    public string RollNumber { get; set; }
    public string Subject { get; set; }
}

Automatically POCO (Plain old CLR Object) is serialized without using DataContract attribute. So to test this, let us create service contract

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        MyCustomData GetData();
    }

And service implementation is as below


    public class Service1 : IService1
    {
        public MyCustomData GetData()
        {
            MyCustomData data = new MyCustomData { Name = "John", RollNumber = "1", Subject = "WCF" };
            return data;
        }
    }

So when we consume this service at client side

clip_image002

We can use that as above

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Service1Client proxy = new Service1Client();
            MyCustomData data = proxy.GetData();
            Console.WriteLine(data.Name + data.Subject + data.RollNumber);
            Console.ReadKey(true);
        }
    }
}

Now we know how we could serialize custom data or class without using DataContractSerlializer. But if we notice all the public property are serialized. If we want to hide some of public property from serialization then we will use IgnoreDataMember

 public class MyCustomData
    {

        public string Name { get; set; }
        [IgnoreDataMember]
        public string RollNumber { get; set; }
        public string Subject { get; set; }
    }

Add the namespace System.RunTime.Serilization to work with IgnoreDataMember attribute.

Now we are hiding public property RollNumber with IgnoreDataMember attribute , so at the client side when we try to access RollNumber property on custom class MyCustomData we will get the below compile time error.

clip_image004[5]

Error says there is no definition for RollNumber is present at the client side.

Create a SQL Login user in SQL Server 2008

This article will give a walkthrough on creating a SQL Login user.

Step 1

Login to SQL Server 2008 instance using windows authentication

clip_image001

Step 2

Right click on server instance name and select properties.

clip_image002

Step 3

Property window will be open. In that select the Security tab.

clip_image004

In server authentication tab you can see your SQL Server in configured for

1. Windows authentication mode

2. SQL Server and Windows Authentication mode

So if you want to enable SQL User login to SQL Server then select checked mixed mode here .

clip_image005

And then click ok. Now SQL Server is configured for mixed mode login.

Step 4

Now to create SQL LOGIN, right click on Security tab and select New and then Login .

clip_image006

Step 5

When you click on Login you will get the below window

clip_image008

Give the Login Name

clip_image009

Select SQL Server Authentication and provide your desired password

clip_image010

Disable Enforce password policy

clip_image011

Select default database

clip_image012

Leave default language and click OK to create a new SQL Server login

Now in object explorer you can see User1 login .

clip_image013

Now at time of connecting to SQL Server login User1 can be used.

Inserting element in sorted Generic list (List) using binary search in C#

I got a mail asking,

“How we could insert an item in sorted generic list such that after insertion list would be remaining sorted?”

Answer of this is using Binary Search

As we know Binary search works on Divide and conquer algorithm. And running time using Binary search is very efficient.

So we need to follow below algorithm

Step 1

Sort the list

Step 2

Save the value to be inserted in a variable

Step 3

Do the binary search of the inserted variable in the list.

clip_image002

Step 4

Insert the item at the compliment of the number returned by the binary search.

Example #1 inserting a string in sorted list of string.

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace ConsoleApplication21
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> lstMyString = new List<string>();
            lstMyString.Add("Apple");
            lstMyString.Add("Mango");
            lstMyString.Add("Banana");
            lstMyString.Add("papya ");
          foreach (var r in lstMyString)
            {
                Console.WriteLine(r);
            }
            Console.ReadKey(true);
     }

Output

clip_image004

Now if in above sorted list we need to add one more string item cashew.

clip_image006

So first we need to perform the binary search and then find the index of the next top element by negating the integer returned by the Binary search.

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace ConsoleApplication21
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> lstMyString = new List<string>();
            lstMyString.Add("Apple");
            lstMyString.Add("Mango");
            lstMyString.Add("Banana");
            lstMyString.Add("papya ");
            lstMyString.Sort();
            string strToInsert = "Cashew";
            int binraySearchIndex =  lstMyString.BinarySearch(strToInsert);
            if (binraySearchIndex < 0)
            {
                lstMyString.Insert(~binraySearchIndex, strToInsert);
            }
            foreach (var r in lstMyString)
            {
                Console.WriteLine(r);
            }
            Console.ReadKey(true);
              }

Ouput

clip_image008

Example #2: Inserting a custom class in list of custom class .

I have a class called Product

Product.cs


   class Product
    {
        public string ProductName { get; set; }
        public int ProductPrice { get; set; }
    }

And List of Product as below,


 List<Product> prdList = new List<Product>()
            {
               new Product {ProductName = "Apple",ProductPrice = 101},
                new Product {ProductName = "Apple",ProductPrice = 99},
                new Product {ProductName = "Pen",ProductPrice = 99},
                new Product {ProductName = "Pencil", ProductPrice = 100},
                new Product {ProductName ="Apple", ProductPrice = 100},
                new Product { ProductName = "Mango", ProductPrice = 35},
                new Product {ProductName = "Shirt", ProductPrice=200}
            };

Now first let us sort this list.

clip_image009

How to sort a Generic List? Read here

Now in sorted list of Product we need to insert one more product such that it should be inserted in sorted order in the list.

clip_image011

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace ConsoleApplication21
{
    class Program
    {
        static void Main(string[] args)
        {
            int tempPrevious = 0;
            int tempcurrent = 0;
            IComparer<Product> compare = new CompareProduct();
            List<Product> prdList = new List<Product>()
            {
               new Product {ProductName = "Apple",ProductPrice = 101},
                new Product {ProductName = "Apple",ProductPrice = 99},
                new Product {ProductName = "Pen",ProductPrice = 99},
                new Product {ProductName = "Pencil", ProductPrice = 100},
                new Product {ProductName ="Apple", ProductPrice = 100},
                new Product { ProductName = "Mango", ProductPrice = 35},
                new Product {ProductName = "Shirt", ProductPrice=200}
            };
            prdList.Sort(compare.Compare);
             int search = 0;
            Product productToInsert = new Product {
                                        ProductName = "Ball",
                                        ProductPrice = 30 };
            search = prdList.BinarySearch(productToInsert, (IComparer<Product>)compare);
            if (search < 0)
            {
                prdList.Insert(~search, productToInsert);
            }
            foreach (Product p in prdList)
            {
                tempcurrent = p.ProductPrice;
                if (tempcurrent != tempPrevious)
                {
                    Console.WriteLine("**********************");
                    Console.WriteLine("Price = " + p.ProductPrice);
                }
                Console.WriteLine(p.ProductName);
                tempPrevious = p.ProductPrice;
            }
            Console.ReadKey(true);
        }
    }

Output

clip_image013

For reference generic sort class for list of Product is as below

CompareProduct.cs


 class CompareProduct : IComparer<Product>
    {
        public   int Compare(  Product p1,   Product p2)
        {
            int result;
            if (Product.ReferenceEquals(p1, p2))
            {
                result = 0;
            }
            else
            {
                if (p1 == null)
                {
                    result = 1;
                }
                else if (p2 == null)
                {
                    result = -1;
                }
                else
                {
                    result = NumberCompare(p1.ProductPrice, p2.ProductPrice);
                    //result = StringCompare(p1.ProductName, p2.ProductName);
                    if (result == 0)
                    {
                       // result = NumberCompare(p1.ProductPrice, p2.ProductPrice);
                        result = StringCompare(p1.ProductName, p2.ProductName);
                    }
                }
            }
            return result;
        }
         int StringCompare(string strFirstString, string secondString)
        {
            int result;
            if (strFirstString == null)
            {
                if (secondString == null)
                {
                    result = 0;
                }
                else
                {
                    result = 1;
                }
            }
            else
            {
                result = strFirstString.CompareTo(secondString);
            }
            return result;
        }
         int NumberCompare(int number1, int number2)
        {
            int result;
            if (number1 > number2)
            {
                result = 1;
            }
            else if (number1 < number2)
            {
                result = -1;
            }
            else
            {
                result = 0;
            }
            return result;
        }
    }
}

Sorting a Generic List in C#

Objective

This article will give code snippet on how to sort a generic list in C#

I have a class called Product

Product.cs


class Product
    {
        public string ProductName { get; set; }
        public int ProductPrice { get; set; }
    }

And List of Product as below,


 List<Product> prdList = new List<Product>()
            {
               new Product {ProductName = "Apple",ProductPrice = 101},
                new Product {ProductName = "Apple",ProductPrice = 99},
                new Product {ProductName = "Pen",ProductPrice = 99},
                new Product {ProductName = "Pencil", ProductPrice = 100},
                new Product {ProductName ="Apple", ProductPrice = 100},
                new Product { ProductName = "Mango", ProductPrice = 35},
                new Product {ProductName = "Shirt", ProductPrice=200}

            };

Now we need to sort the above generic list in ascending order.

1. On ProductPrice

2. And then on ProductName

So our expected output would be something like,

clip_image002

What we are going to do here is that, first we will sort the list in productprice and then group they and then we will sort them on productName.

Steps are as follows

1. Create a class and implement IComparer<T>

2. Define the compare function. Give sorting logic here.

3. Pass the compare function as the parameter of sort method of list.

Step 1

clip_image004

Here Product is the class we are going to sort. You are free to give any name of the class.

Step 2

Define compare function

clip_image006

Step 3

Pass the compare function as parameter of sort method.

clip_image007

Here prdList is generic list of Product. And compare is object of class CompareProduct.

CompareProduct.cs


class CompareProduct : IComparer<Product>
    {

        public   int Compare(  Product p1,   Product p2)
        {
            int result;
            if (Product.ReferenceEquals(p1, p2))
            {
                result = 0;
            }
            else
            {
                if (p1 == null)
                {
                    result = 1;
                }
                else if (p2 == null)
                {
                    result = -1;

                }
                else
                {
                    result = NumberCompare(p1.ProductPrice, p2.ProductPrice);
                    //result = StringCompare(p1.ProductName, p2.ProductName);
                    if (result == 0)
                    {
                       // result = NumberCompare(p1.ProductPrice, p2.ProductPrice);
                        result = StringCompare(p1.ProductName, p2.ProductName);
                    }

                }
            }

            return result;
        }
         int StringCompare(string strFirstString, string secondString)
        {
            int result;

            if (strFirstString == null)
            {
                if (secondString == null)
                {
                    result = 0;
                }
                else
                {
                    result = 1;
                }
            }
            else
            {
                result = strFirstString.CompareTo(secondString);
            }
            return result;


        }


         int NumberCompare(int number1, int number2)
        {
            int result;

            if (number1 > number2)
            {
                result = 1;
            }
            else if (number1 < number2)
            {
                result = -1;
            }
            else
            {
                result = 0;
            }
            return result;


        }

Now we need to use ProductCompare class to sort the list as of our requirement.

Program.cs


namespace ConsoleApplication21
{
    class Program
    {
        static void Main(string[] args)
        {
            int tempPrevious = 0;
            int tempcurrent = 0;
            CompareProduct compare = new CompareProduct();
            List<Product> prdList = new List<Product>()
            {
               new Product {ProductName = "Apple",ProductPrice = 101},
                new Product {ProductName = "Apple",ProductPrice = 99},
                new Product {ProductName = "Pen",ProductPrice = 99},
                new Product {ProductName = "Pencil", ProductPrice = 100},
                new Product {ProductName ="Apple", ProductPrice = 100},
                new Product { ProductName = "Mango", ProductPrice = 35},
                new Product {ProductName = "Shirt", ProductPrice=200}

            };


            prdList.Sort(compare.Compare);


            foreach (Product p in prdList)
            {
                tempcurrent = p.ProductPrice;

                if (tempcurrent != tempPrevious)
                {
                    Console.WriteLine("**********************");
                    Console.WriteLine("Price = "+ p.ProductPrice);

                }
                Console.WriteLine(p.ProductName);
                tempPrevious = p.ProductPrice;
            }

            Console.ReadKey(true);

        }
    }

When we run output would be

clip_image009

Removing .SVC from WCF REST Service

I got a mail asking question, “How could we remove .SVC from a WCF REST Service?

For example, instead of

clip_image001

We need to remove, .svc extension from address of the WCF service.

Let us say, you have a WCF REST Service up and running

http://localhost:58230/Service1.svc/GetMessage

With output

clip_image003

Read here: How to create a WCF REST Service

To remove service extension, we will write a HTTP Module and remove the extension and rewrite the path.

Now to remove .svc follows below steps

1. Add a class in WCF Application project.

2. Add the namespace System.Web

3. Implement the class from IHttpModule

clip_image004

4. Before starting of current context take the context path and rewrite the URL.

clip_image006

Full source code for

RemoveSvc.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WcfService7
{
    public class Removesvc : IHttpModule
    {
        public void Dispose()
        {
        }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += delegate
            {
                HttpContext cxt = HttpContext.Current;
                string path = cxt.Request.AppRelativeCurrentExecutionFilePath;
                int i = path.IndexOf('/', 2);
                if (i > 0)
                {
                    string a = path.Substring(0, i) + ".svc";
                    string b = path.Substring(i, path.Length - i);
                    string c = cxt.Request.QueryString.ToString();
                    cxt.RewritePath(a, b, c, false);
                }
            };
        }
    }
}

5. Now we need to add the HTTP Module in configuration file of WCF Service.

clip_image008

Where, RemoveSvc is name of the class implementing IHttpModule and WcfService7 is the project name (namespace)

Web.Config


<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules>
      <add name ="removesvc" type ="WcfService7.Removesvc,WcfService7"/>
   </modules>      
  </system.webServer
</configuration>


6. Now host the service in IIS. [Read here : Hosting WCF Service in IIS ]

Now when you open WCF REST Service in browser, you can see you are able to call the service without extension ,

http://localhost:4567/Service1/GetMessage

clip_image010

Consuming WCF REST Service in ASP.Net Web Site

Objective

This article will give a quick walkthrough on how to consume a WCF REST Service in ASP.Net Web site.

1. Create a WCF REST Service.

2. Consume the Service in ASP.Net Web Site

Create a WCF REST Service

Step 1

Create a WCF application. To create a new application File -> New -> Web-> WCF Service Application.

clip_image002

Step 2

Remove all the default code created by WCF. Remove code from IService 1 interface and Service1 class. Remove the code from Web.Config also. Open Web.Config and remove System.Servicemodel codes.

Step 3

Right click on Service1.svc select View markup and add below code

clip_image003

<%@ ServiceHost Language=”C#” Debug=”true” Service=”FetchingImageinBrowser.Service1″ CodeBehind=”Service1.svc.cs” Factory=”System.ServiceModel.Activation.WebServiceHostFactory” %>

Step 4

Create contract. Operation contract will return Stream. Stream is in the namespace System.IO. By putting WebGet attribute make operation contract

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.ServiceModel.Web;
namespace WcfService6
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebGet(UriTemplate="/GetData")]
        string GetData();
    }
}

Step 5

Implement the service

Service1.svc.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService6
{
    public class Service1 : IService1
    {
        public string GetData()
        {
            return "hello From REST ";
        }
    }
}

Press F5 to run the service

Consume the Service in ASP.Net Web Site

Step 1

Create an ASP.Net Web Site. Navigate to File -> New -> Web Site

clip_image005

Step 2

Drag and drop one button and text box on the page.

Step 3

Add the namespace of

System.RunTIme.Serilization

System.Net

System.IO

Step 4

On the click event of the button,

clip_image007

In above code,

1. Create instance of WebClient class.

2. Down load the data in byte array form.

3. Create the stream from byte array

4. Using Data Contract Serializer deserialize the stream.

5. Get the result in string

Default.aspx.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.Net;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        WebClient proxy = new WebClient();
        byte[] abc = proxy.DownloadData((new Uri("http://localhost:4567/Service1.svc/GetData")));
        Stream strm = new MemoryStream(abc);
        DataContractSerializer obj = new DataContractSerializer(typeof(string));
        string result = obj.ReadObject(strm).ToString();
        TextBox1.Text = result;
    }
}

Run to get the output.

WCF 4.0 service consumed in Silverlight 4.0 avoiding cross domain problem

Objective

This article will explain how to call WCF 4.0 service hosted in IIS 7.5 in a Silverlight application. This article will explain the way to avoid cross domain problem also.

Expected Output

clip_image001

When user will click on + button a WCF service hosted on IIS will get called. As a input parameter to service value from two text box will be passed and result from the service will get display in result text box.

clip_image002

Create WCF Service

Create WCF service. Open visual studio select new project and then from WCF tab select WCF Service application to create a new WCF service.

clip_image004

Delete the default code created by WCF from IService1 and Service1.svc.cs

a. So delete the data contract

b. Modify the service contract as below. Just make one operation contract to return a string.

IService1.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService5
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string  GetMessage(string  number1 , string number2);

    }
}

Now implement the service as below,

Service1.svc.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService5
{
    public class Service1 : IService1
    {
        public string GetMessage(string number1, string number2)
        {
            return (Convert.ToInt32(number1) + Convert.ToInt32(number2)).ToString();
        }
    }
}

Since, we are creating WCF Service for SilverLight client, so we need to modify the endpoint of the service with basicHttpBinding.

As we know SilverLight supports either basicHttpBinding or webHttpBinding. webHttpBinding is essentially for REST based service . We are going to use basicHttpBinding to enable SOAP based WCF service for SilverLight client.

1. Declare the end point with basicHttpBinding.

clip_image005

2. Declare the Meta data exchange end point.

clip_image006

3. Define the service behavior

clip_image008

So the service will look like

clip_image010

Web.Config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name ="svcbh">         
          <serviceMetadata httpGetEnabled="true"/>         
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name ="WcfService5.Service1" behaviorConfiguration ="svcbh">
        <endpoint name ="SilverLightendpoint"
                  address =""
                  binding ="basicHttpBinding"
                  contract ="WcfService5.IService1"/>
        <endpoint name ="MetaDataSilverlightEndpoint"
                  address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"/>
      </service>
    </services>
    <!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />-->
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer
</configuration>

Hosting in IIS and solving the cross domain problem

Host the service in IIS. Please read here step by step to host WCF 4.0 Service in IIS 7.5

Solving cross domain problem

1. Right click on WCF Service project and add new item. Select XML file from Data tab.

clip_image012

2. Give the name of the XML file clientaccesspolicy.xml


clip_image014

3. Add the below markup in ClientAcccessPolicy.xml file

clip_image016

So, finally now you will have a ClientAccesspolicy.xml file in WCF project

ClientAccesspolicy.xml

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction,Content-Type">
        <domain uri="*" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

4. Now open WCF Service project in windows explorer. To do this right clicks on the project and select open folder in Window explorer.

clip_image018

Copy clientaccesspolicy.xml file and paste it in C:\inetpub\wwwroot. Make sure in wwwroot folder clientaccesspolicy.xml file exist.

Consuming in SilverLight 4.0


1. Create a Silver Light project by Project->new ->SilverLight -> SilverLight Application

clip_image020

And create a web site to host Silver light application.

clip_image021

2. Now design the page in XAML.

clip_image022

MainPage.xaml

<UserControl x:Class="SilverlightApplication3.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
  <Grid x:Name="LayoutRoot" Background="Gray" Height="200" Width="300">
    <Grid.RowDefinitions>
      <RowDefinition Height="*" />
      <RowDefinition Height="2*" />
    </Grid.RowDefinitions>
    <TextBox x:Name="txtResult" Height="40" Text="" Margin="12,14,22,14" />
    <StackPanel Orientation="Horizontal" Grid.Row="1" >
      <Canvas>
        <TextBox x:Name="txtNumber1" Height="40" Width="99"  Canvas.Left="20" Canvas.Top="30"/>
        <Button x:Name="btnAdd" Height="40" Width="50" Content="+" Canvas.Left="120" Canvas.Top="30" />
        <TextBox x:Name="txtNumber2" Height="40" Width="99"  Canvas.Left="170" Canvas.Top="30"/>
      </Canvas>
    </StackPanel>
  </Grid>
</UserControl>

Explanation

1. Divided the main grid in two rows.

2. In first row put a textbox to display the result.

3. In second row put a stack panel with horizontal orientation.

4. Put a canvas inside stack panel

5. Put two text box and button in canvas.

3. Right click on SilverLight project and add Service Reference.

clip_image023

Give the URL of the WCF service hosted in IIS in Address text box. And then click GO.

clip_image024

4. Calling the Service

Add namespace

clip_image025

On click event of the button

clip_image027

Explanation

1. Silverlight calls WCF service asynchronously

2. So first completed event is getting called. If operation contract name is GetMessage then event name will be GetMessageCompleted.

3. After event aysnc function is being called.

MainPage.Xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverlightApplication3.ServiceReference1;

namespace SilverlightApplication3
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            btnAdd.Click += new RoutedEventHandler(btnAdd_Click);
        }

        void btnAdd_Click(object sender, RoutedEventArgs e)
        {

            Service1Client proxy = new Service1Client();
            proxy.GetMessageCompleted += delegate(object sender1, GetMessageCompletedEventArgs e1) { txtResult.Text = e1.Result;};
            proxy.GetMessageAsync(txtNumber1.Text ,txtNumber2.Text);

        }

    }
}

Output

clip_image001[1]

Conclusion

In this article we saw how we can consume WCF Service in Silverlight application with cross domain. I hope this article was useful. Thanks for reading. Happy Coding

Walkthrough on creating WCF 4.0 Service and Hosting in IIS 7.5

Objective

This article will give step by step walkthrough

1. How to create a basic WCF 4.0 Service?

2. How to host WCF Service in IIS 7.5?

3. Hot to test service in a client.

Create WCF Service

Create WCF service. Open visual studio select new project and then from WCF tab select WCF Service application to create a new WCF service.

clip_image002

Delete the default code created by WCF from IService1 and Service1.svc.cs

a. So delete the data contract

b. Modify the service contract as below. Just make one operation contract to return a string .

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService5
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetMessage();

    }
}

Service1.svc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService5
{
    public class Service1 : IService1
    {
        public string GetMessage()
        {
            return "Hello From WCF Service ";
        }
    }
}

Leave the default configuration created by WCF.

Web.Config

<?xmlversion="1.0"?>
<configuration>
  <system.web>
    <compilationdebug="true"targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>         
          <serviceMetadatahttpGetEnabled="true"/>         
          <serviceDebugincludeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironmentmultipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modulesrunAllManagedModulesForAllRequests="true"/>
  </system.webServer
</configuration>

Host WCF Service in IIS 4.0

Open IIS

a. Open the command prompt in administrator mode. To do click on Start button then type RUN in search and then in Run window type inetmgr to open IIS .

clip_image003

Now you will have IIS open like below

clip_image005

b. Right click on Sites and then click Add Web Site

clip_image006

c. Now a window will open.

clip_image007

Give any name of your choice as the site name. I am giving name here HostedWcfService

clip_image008

Now click on select and choose ASP.Net v4.0 from the drop down.

clip_image009

Now in the physical path section, we need to give physical path of the service. So to get the physical path of the service, right click on the WCF Service project in visual studio and click open project in windows explorer. Open the project in windows explorer and from address bar copy the path and paste that below. Or you can browse also. Just click on browse button and navigate to project folder of the WCF Service.

clip_image010

Now at the Binding section select HTTP. Give any port number. I am selecting the port as 4567

clip_image011

Do not give any name as host name. Leave it blank

clip_image012

Check the check box Start Web Site Immediately.

clip_image013

And now click OK on the window.

d. Now open visual studio command prompt in administrator mode. Right click and select as administrator

clip_image014

clip_image015

Type the below command

aspnet_regiis.exe /iru

clip_image017

You will get the message Finished Installing ASP.Net 4.0

e. Now go to inetmgr, you would able to see the site you just created in previous step.

clip_image018

Publishing the WCF Service

Go back to WCF Service. Right click and select Publish

clip_image019

On clicking of publish a window will come.

clip_image020

Give a Service URL. You are free to give any Service URL here. Just make sure host name is geeting resolved. In stead of localhost you can give IP address or your machine name also.

clip_image021

Give the name of the site HostedWcfService. We created this site in previous step.

clip_image022

Leave the credential inactive.

clip_image023

Now click on Publish.

clip_image024

You will get the message in bottom publish succeeded

Browsing the service hosted in IIS

Open Inetmgr and right click on site HostedWcfService. Then from Manage Web Site select Browse option.

clip_image025

When you click on browse site will get open in browser

clip_image027

You will get the above error. Just in address bar append Service1.svc with the address to open the service in browser.

http://localhost:4567/Service1.svc

And in browser you will get the service up and running.

clip_image029

So now you successfully created and hosted the WCF 4.0 service in IIS 7.5

Testing the Service at client

a. Create console application project.

clip_image031

b. Right click and add the service reference.

clip_image032

c. Give in address the address of service hosted in IIS and click GO.

clip_image033

d. Call the service as below ,

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Service1Client proxy = new Service1Client();
            Console.WriteLine(proxy.GetMessage());
            Console.Read();
        }
    }
}

Output

clip_image035

 

Conclusion

In this article we saw,

How to create a basic WCF 4.0 Service?

How to host WCF Service in IIS 7.5?

Hot to test service in a client.

I hope this article was useful. Thanks for reading. Happy coding.