WCF self hosted service over HTTPS

In this post I will show you how to host self hosting wcf service over ssl.

Let's create a simple wcf service


Create a new console application in visual studio and paste the following code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SelfHostSSL
{
    [ServiceContract]
    public interface IGreeting
    {
        [OperationContract]
    string SendGreeting();
    }
    public class Implementation : IGreeting
    {
        
    public string SendGreeting()
        {
    return "Hello world";
        }
        
    }
    class Program
    {
    static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(Implementation));
            host.Open();
            Console.WriteLine("Service is ready");
            Console.ReadLine();
        }
    }
}

After that add new item app.config and paste following code in it

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
    <system.serviceModel>
    <behaviors>
    <serviceBehaviors>
    <behavior name="serviceBehav">
    <serviceDebug />
    <serviceMetadata httpGetEnabled="true" httpGetUrl="mex" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <services>
    <service behaviorConfiguration="serviceBehav" name="SelfHostSSL.Implementation">
    <endpoint address="basic" binding="basicHttpBinding"
    bindingConfiguration="" contract="SelfHostSSL.IGreeting" ></endpoint>
    <host>
    <baseAddresses>
    <add baseAddress="http://localhost:4490/"/>
    </baseAddresses>
    </host>
    </service>
          
    </services>
      
    </system.serviceModel>
</configuration>


Add new project named Client in same solution and paste following code in it


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Client
{
    [ServiceContract]
    public interface IGreeting
    {
        [OperationContract]
    string SendGreeting();
    }
    
    class Program
    {
    static void Main(string[] args)
        {
            ChannelFactory<IGreeting> proxy = new ChannelFactory<IGreeting>(new BasicHttpBinding());
            proxy.Endpoint.Address = new EndpointAddress("http://localhost:4490/basic");
    string result = proxy.CreateChannel().SendGreeting();
            Console.WriteLine(result);
        }
    }
}

Our simple wcf service is ready now.Let's configure it for ssl. Open app.config and make highlighted changes

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="serviceBehav" name="SelfHostSSL.Implementation">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="serviceBinding" contract="SelfHostSSL.IGreeting"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8080/basic"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
    <basicHttpBinding>
    <binding name="serviceBinding">
    <security mode="Transport">
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehav">
          <serviceDebug/>
          <serviceMetadata httpsGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

When you run the service after making above changes service will throw following exception.


AddressAccessDeniedException: HTTP could not register URL http://+:8080/<…>.  Your process does not have access rights to this namespace.



To fix this problem, the owner of the HTTP namespace (built-in administrator) needs to delegate this ownership to the user account under which you are running your application (most of the times, it's the logged on user). To do this, start a command prompt using "Run as administrator" so that you have elevated privileges. Then, use netsh.exe to give some of the Administrator's HTTP namespace to your user account. You can look at the existing HTTP namespace delegations by using "netsh http show urlacl".





Execute the above command and run the service.If every thing is fine then you will see "service ready " message.

Try to browse the service from browser you will see page can not found error message

This is because our port is not open for SSL.Now you have to create a self -signed certificate for this follow the following two links and create a self signed certificate and note down the thumbprint value a remove the extra space.

How to create Self-Signed SSL Certificate using OpenSSL

How to create self signed certificate using makecert 

Now,It's time to configure the port for SSL (check out this for more details)
Open the command prompt in elevated mode and run the following command


Command Description:

netsh http add sslcert [Ipaddress:port] certhas=[thumbprint of certifcate] appid={unique id for application.you can use GUID for this]

How to create Self-Signed SSL Certificate using OpenSSL

In this
        post I will show you how to create a Self-Signed certificate using OpenSSL.


Generate Private Key and Certificate Signing Request

A private key and certificate signing request are required to create an SSL certificate. These can
be generated with a few simple commands.




C:\> openssl genrsa -des3 -out localhost.key 1024 
---------------------------------------------
Enter pass phrase for site.key: 
Verifying - Enter pass phrase for site.key: 
C:\> mv localhost.key localhost.org.key 
C:\> openssl rsa -in localhost.org.key -out localhost.key 
Enter pass phrase for localhost.org.key:
writing RSA key 
C:\> openssl req -new -key localhost.key -out server.csr
----------------------------------------------------            
Country Name (2 letter code) [AU]:IN 
State or Province Name (full name) [Some-State]:HR


Generate SSL Certificate

C:\> openssl x509 -req -days 365 -in server.cer -signkey localhost.key -out final.cer
The final.cer  file is your site certificate suitable for use with WCF service

Project Euler Problem4[C#]


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

namespace ProjectEuler
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Problem4(600851475143UL));

        }
        /// <summary>
        /// http://projecteuler.net/problem=3
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static ulong Problem4(ulong number)
        {
            ulong i = 2;
            while (i * i < number)
            {
                while (number % i == 0)
                {
                    number = number / i;

                }
                i = i + 1;
            }
            return number;

        }

    }
}

Project Euler Problem2 [c#]


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

namespace ProjectEuler
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Problem2());
        }

        /// <summary>
        /// http://projecteuler.net/problem=2
        /// </summary>
        /// <returns></returns>
        public static ulong Problem2()
        {
            var sum = Fibonacci().Where(x => x % 2 == 0)
                                 .TakeWhile(x => x < 4000000)
                                 .Aggregate((add, x) => add + x);
            return sum;
        }

        public static IEnumerable<ulong> Fibonacci()
        {
            var a = 0UL;
            var b = 1UL;
            var c = a + b;

            while (true)
            {
                yield return c;

                c = a + b;
                a = b;
                b = c;
            }


        }
    }
}

Project Euler Problem1 [C#]


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

namespace ProjectEuler
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Problem1());
        }
        /*If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of                these multiples is 23.
          Find the sum of all the multiples of 3 or 5 below 1000.*/

        public static int Problem1()
        {
            var sum = Enumerable.Range(1, 999)
                    .Where(x => x % 3 == 0 || x % 5 == 0)
                    .Sum();
            return sum;
        }

    }
}

How to used google chart in asp.net[google chart]

In this post,I will show you how to display google chart in asp.net.Before going to implementation details,go through the following link


Visualization: Pie Chart


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PieChart.aspx.cs" Inherits="PiChart" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>jQuery Google Chart Demo</title>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript">
        google.load("visualization", "1", { packages: ["corechart"] });
    function drawChart() {
    var hdValue = document.getElementById("<%=hdData.ClientID%>").value;
    var response = $.parseJSON(hdValue);
    var data = new google.visualization.DataTable();
            data.addColumn('string', 'TaskType');
            data.addColumn('number', 'HoursPerDay');
    for (var i = 0; i < response.length; i++) {
    var row = new Array();
                row[0] = response[i].TaskType;
                row[1] = parseInt(response[i].HoursPerDay);
                data.addRow(row);
            }
    var options = {
                title: 'My Daily Activities'
            };
            chart = new google.visualization.PieChart(document.getElementById('chart_div'));
            chart.draw(data, options);
        }
    </script>
    <script type="text/javascript">
        $(document).ready(drawChart);
      
    </script>
</head>
<body>
    <form id="dform" runat="server">
    <div id="chart_div" style="width: 900px; height: 500px;">
    </div>
    <asp:HiddenField ID="hdData" runat="server" />
    </form>
</body>
</html>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Web.Script.Serialization;
public partial class PiChart : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    if (!IsPostBack)
        {
            StringBuilder data = new StringBuilder();
            JavaScriptSerializer json = new JavaScriptSerializer();
            json.Serialize(GetSampleData(), data);
            hdData.Value = data.ToString();
        }
    }
  
    private List<Task> GetSampleData()
    {
        List<Task> tasks = new List<Task>
            {
    new Task{TaskType="Work",HoursPerDay=11},
    new Task{TaskType="Eat",HoursPerDay=2},
    new Task{TaskType="Commute",HoursPerDay=2},
    new Task{TaskType="Watch TV",HoursPerDay=2},
    new Task{TaskType="Sleep",HoursPerDay=7},
            };
    return tasks;
    }
    public class Task
    {
    public string TaskType { get; set; }
    public int HoursPerDay { get; set; }
    }
}