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