Solving Caching problem of IE for WCF REST service

Objective

This article will explain; how to solve the caching problem in IE while making call to for REST enabled WCF service. Client might be a SILVERLIGHT client or AJAX client.

Background

Read my other articles on WCF REST service for better understanding of this article.

Is REST service and a web page is same?

Theory says YES, these two are almost the same entity exist on web. Calling a REST service is exactly the same as of browsing the web page on the web.

REST is architecture to create service not a specification. And it works on the HTTP verbs.

REST stands for Representational state transfer where each operation in a service is uniquely identified. Each operation has their, own unique URI and can be accessed via this URL all across the web. Each operation in service definition is attributed with the HTTP verbs they are going to work with. So if URL of a REST service is browsed from the browser, it will return response from the service in form of either JSON or XML base on the service definition.

So, the below link can be browsed in browser.

http://localhost:80/Service1.Svc/GetName?deptId=9

Temporary Internet Files and History Settings

There are four options for cache settings in Internet Explorer


 

Every Time I visit the Web Page

On returning of the page which has been viewed previously, IE checks on the server whether viewed page has been changed. If viewed page has been changed, IE will display the new changed page else it will display the cached page.

Note: If this setting is selected in browser there is no need of handle the caching through code. There is no caching for this option.

Every Time I Start Internet Explorer

In this option IE will download the newer version from the server only when browser got reopened or refreshed [F5]. Else each time IE will show the cached page.

Automatically

In this option IE download the new page from the server based on certain algorithm. This is default setting of the browser.

Never

In this option IE never go to server to download the page. Always browser shows the cached page.

Bottom Line is, since
browsing web page and REST Service call is exactly the same so browser setting applies to calling REST service also. So caching problem does apply to REST service call also.

How to solve caching problem?

There are two ways to solve the caching problem of REST service call.

  1. Through work around
  2. Through JQuery

Through Work Around

Let us suppose service is

[WebGet(ResponseFormat = WebMessageFormat.Json)]

[OperationContract]


List<string> GetNames(string deptId);

 

Service is hosted somewhere and service is being called by,

AJAX cleint

$.getJSON(‘Service1.svc/ GetNames,

{ deptId: ids },

function(data,status){}

 

Silver Light Client

HttpClient proxyClient = new
HttpClient();

proxyClient.TransportSettings.Credentials = CredentialCache.DefaultCredentials;

string targetURI = string.Format(“/Service1.svc?deptId={0}”,deptId);

HttpResponseMessage response = proxyClient.Get(targetURI);

 

Now, if service is being called with the deptId=9; then URL of calling service will be

http://localhost:80/Service1.Svc/GetName?deptId=9

And a response will get cached at the client browser.

Problem Statement

Now consider and scenario, when for the deptId =9 database has been changed at the service side. If browser is set as the default (Automatic) and for the next service call with same dept id, browser will call the URL http://localhost:80/Service1.Svc/GetName?deptId=9 , and response for this URL has been cached at the browser, so at the client side changed database won’t be reflected.

Solution

This is a work around solution; just add an extra parameter of type DateTime in service and each time at calling the service pass current date time from the client. So each time there will be a unique URL and that won’t be cached. So each time browser will download the latest response from the server regardless of the browser setting.

Modify service as

[WebGet(ResponseFormat = WebMessageFormat.Json)]

[OperationContract]


List<string> GetNames(string currentDateTime, string deptId);

 

So now at time of calling the service just pass the current date time and it will modify the Service URL each time. So browser will get the response from the service each time.

http://localhost:80/Service1.Svc/GetName?currentDateTime=12-12-2009:10.00.00,deptId=9

After 1 sec the service call will get modify with the URL and this is new URL .

http://localhost:80/Service1.Svc/GetName?currentDateTime=12-12-2009:10.00.01,deptId=9

Through JQuery

This solution is only applicable for the AJAX client.

  1. Call $.ajaxSetup({ cache: false }); before making the service call.
  2. Call $.ajaxSetup({ cache: true }); after making the service call.
$.ajaxSetup({ cache: false });

$.getJSON(‘Service1.svc/ GetNames,

{ deptId: ids },

function(data,status){}

$.ajaxSetup({ cache: true });


Conclusion

This article explained about working with cache problem in IE while making call to REST enabled WCF service. Thanks for reading.

NTLM and Windows Authentication on WCF service

Objective

This document will explain various combinations of IIS and WCF Ntlm/Windows authentication settings.

What is difference between NTLM and WINDOWS authentication in WCF?

Windows authentication = authentication in NTLM + authentication in Active Directory

NTLM authentication = authentication in only NTLM

IIS configuration

For all scenario IIS is configured for Windows authentication. What I mean is Windows Authentication is enabled and all other authentication is disabled. Navigate to below path to open ApplicationHost.Config file of IIS.

C:\Windows\System32\inetsrv\config\applicationHost.config

Binding used in WCF service

For all scenario basicHttpBinding being used for WCF service.

Scenario #1

Default setting for IIS Applicationhost.Config is

<windowsAuthentication enabled=false>

<providers>

<add value=Negotiate />
<add value=NTLM />
</providers>
</windowsAuthentication>

If IIS APP.Config file is having default setting, then we can have any authentication for WCF service corresponding IIS configured; WCF service will run as expected without any error.

Note: SharePoint is running as expected

Browsers Behavior with default settings

  1. IE 7.0 is not asking for authentication
  2. Fire Fox 3.5.6 is asking user to authenticate
  3. Safari 4.0.4 is asking user to authenticate

Scenario #2

If IIS Applicationhost.Config File setting has been modified as below, where forcefully Windows authentication is enabled for Kerberos then we have to modify service with Windows authentication.

<windowsAuthentication enabled=true><providers>
<add value=Negotiate />
<!–<add value=”NTLM” />–>
</providers>
</windowsAuthentication>

WCF configuration setting for Windows authentication should be

<basicHttpBinding>

<binding name=BasicHttpBinding>
<security mode =TransportCredentialOnly>
<transport lientCredentialType =Windows/>
</security>
</binding>
</basicHttpBinding>

 

Note: SharePoint is running as expected

Browsers Behavior with default settings

  1. IE 7.0 is not asking for authentication
  2. Fire Fox 3.5.6 is asking user to authenticate
  3. Safari 4.0.4 is asking user to authenticate

Scenario #3

If IIS Applicationhost.Config File setting has been modified as below, where forcefully Windows authentication is enabled for NTLM

<windowsAuthentication enabled=true>

<providers>

<!–<add value=”Negotiate” />–>

<add value=NTLM />
</providers>
</windowsAuthentication>

 And we go with Windows authentication for the service, we will get below error

<basicHttpBinding>

<binding name=BasicHttpBinding>

<security mode =TransportCredentialOnly>

<transport clientCredentialType =Windows/>

</security>

</binding>

</basicHttpBinding>

So to remove above error, WCF configuration setting for should be modified for the NTLM authentication.

<basicHttpBinding>

<binding name=BasicHttpBinding>

<security mode =TransportCredentialOnly>

<transport clientCredentialType =Ntlm/>

</security>

</binding>

</basicHttpBinding>

 

Note: SharePoint is running as expected

Browsers Behavior with default settings

  1. IE 7.0 is not asking for authentication
  2. Fire Fox 3.5.6 is asking user to authenticate
  3. Safari 4.0.4 is asking user to authenticate

Summary

Sl No

IIS (Applicationhost.Config ) setting

WCF (Web.config) setting

1 Default Ntlm and Windows Binding behavior
2 Windowauthentication = true and Value = Negotiate Windows authenticated Bidding behavior
3 Windowauthentication = true and Value = Ntlm Ntlm authenticated Binding behavior

So,

  1. If we have ApplicationHost.Config of IIS configured as default, we can have either of Ntlm or Windows authentications for WCF service.
  2. If we have ApplicationHost.Config of IIS configured as Ntlm, we can have only Ntlm authentication for WCF service.

If we have ApplicationHost.Config of IIS configured as Windows, we can have only Windows authentication for WCF service.

Step by Step walkthrough to host WCF service in Windows Azure

Objective

This article will give step by step walkthrough of hosting a WCF service in windows azure.

Note: Before reading through this walkthrough see this http://djoncloud.cloudapp.net/DjService.svc . We are going to host this service in this walkthrough.

Prerequisite

VS 2010 Beta

Windows AZURE SDK should be installed on the system.

Step 1

Open Visual Studio 2010 as an administrator. Select File -> New -> Cloud Service. Click on Windows Azure cloud service template. Give name of the cloud service. After creating the cloud service select the type of role. There are many roles to choose from. For our purpose, we will choose ASP.Net Web Role. After creating ; Now examine the solution explorer. There should be 2 projects. Called WebRole1 and CloudServices1. These names may different basis of the name you given at time of creation of cloud service project in step1.

Step 2

Creating the WCF Service

Right click on WebRole1 project and add new item then select WCF service from the WEB project template.

Modify contract and service implementation as per you. For my purpose , I am making it simple service as below.

Contract

 [ServiceContract]
public interface IDjService
 {
[OperationContract]
string GetMyName(string name);
}

 Service Implementation

public class DjService : IDjService{
public string GetMyName(string name){
return “helllo “ + name + “to my service hosted in Azure”;
} }

 Change the Binding to basicHttpBinding. Make sure to do this.

Note : make sure you have set WebRole1 as startup project .

Step 3

Running on Local Development Fabric (Press F5)

Run the application. This will run on the local development fabric. When we install azure SDK, local development fabric got installed. And when we run the cloud service local development fabric get started and host the application. This provides exactly the same environment as of azure in the cloud. This local development fabric could be used to debug the application before hosting into the cloud.

Running the application on local development fabric

See the URL in address bar of browser, in my case this is

http://localhost:49863/DjService.svc

Step 4

Publishing to cloud (azure)

Right Click on Cloud Service 1 project and select Publish. And publish to azure. See my other articles for details.

Now when you open the URL after publishing , you will get the same page as output you got on the local development fabric. And now you successfully hotsed in cloud.

WCF service hosted in Azure

http://djoncloud.cloudapp.net/DjService.svc

Step 4

Consuming the service hosted in Windows Azure

Create a console application to consume the service. There is a known bug with Azure where a proxy cannot be created from the Azure hosted service. So to as a workaround to create proxy

  1. While adding service reference first adds URL of the service hosted on local development fabric. Copy the URL from Step 3 and right click on Console application and select Add service reference. In service URL paste the URL from step 3.

Call the service hosted in local development fabric like below,

using testingWcfAzureclient.ServiceReference1;
namespace testingWcfAzureclient
{class Program{
static void Main(string[] args)
{
DjServiceClient proxy = new DjServiceClient();
Console.WriteLine(proxy.GetMyName(“Dhananjay “));
Console.Read();
}}}

Output


Open the App.config and modify the address to address of service in azure.

<client><endpoint
address=http://djoncloud.cloudapp.net/DjService.svc
binding=basicHttpBinding
bindingConfiguration=BasicHttpBinding_IDjServicecontract=ServiceReference1.IDjServicename=BasicHttpBinding_IDjService /></client>

Again run the application and you will get the same output.

Step by Step walkthrough to create first application for cloud (Windows Azure)

Step 1

Open Visual Studio 2010 as an administrator. Select File -> New -> Cloud Service. Click on Windows Azure cloud service template. Give name of the cloud service. After creating the cloud service select the type of role. There are many roles to choose from. For our purpose, we will choose ASP.Net Web Role.

Now examine the solution explorer. There should be 2 projects. Called WebRole1 and CloudServices1. These names may different basis of the name you given at time of creation of cloud service project in step1.

CloudService1 project is having two service configuration file.

ServiceDefinition.csdef

This is definition file for the cloud service. This file contains setting like connection string, Endpoints etc.

ServiceConfiguration.csfg

This is configuration file for the cloud service. This contains setting for the roles. This file contains information for number of instance for the service. If we want to increase number of instance for the role only this configuration need to be amend to accommodate the change.

WebRole1 project

This is a simple ASP.Net project. Where we could do whatever we want and could do on an ASP.Net project.

Step 2

Creating the web project

For all our demo purpose, I have modified the aspx page with two buttons and one label and one image control.

Div section of Default.aspx

<div>

<asp:Image ID=”Image1″ runat=”server” ImageUrl=”~/Image0406.jpg”Width=”200px” Height=”300px” />
<asp:Label ID=”lblDisplay” runat=”server” ForeColor=”#FF1166″ Height=”45px” Width=”709px” Font-Bold=”True” Font-Size=”XX-Large”
></asp:Label>
<br/>
<br/>
<asp:Label ID=”lblImageMsg” runat=”server” ForeColor=”Black” Height=”64px” Width=”350pxFont-Bold=”True”>
am I looking good ?!!! LOL
</asp:Label><br/><br/>
<asp:Button ID=”btnClose” runat=”server” ForeColor=”#FF0066″ Height=”64px” Text=”Close my Image”Width=”150px”
onclick=”btnClose_Click”/>
<asp:Button ID=”btnCloud” runat=”server” ForeColor=”#FF0066″ Height=”64px” Text=”Button on Cloud, Hite ” Width=”190px” onclick=”btnCloud_Click”/>
</div>

Default.aspx.cs

namespace WebRole1{

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e){}
protected void btnCloud_Click(object sender, EventArgs e)
{
lblDisplay.Text = ” Hey I have created my first application on Azure ! long to Go!”;
}
protected void btnClose_Click(object sender, EventArgs e)
{
if(string.Equals(btnClose.Text,“Close my Image”,StringComparison.InvariantCultureIgnoreCase)){
Image1.Visible = false;

lblImageMsg.Visible = false;
btnClose.Text =“Show my Image”;
}
else{
Image1.Visible = true;
lblImageMsg.Visible = true;
btnClose.Text =“Close my Image”;
} }}}

Step 3

Running on Local Development Fabric

Run the application. This will run on the local development fabric. When we install azure SDK, local development fabric got installed. And when we run the cloud service local development fabric get started and host the application. This provides exactly the same environment as of azure in the cloud. This local development fabric could be used to debug the application before hosting into the cloud.

Running the application on local development fabric

On clicking at task tray; Local Development Fabric icon would be there. Right click on the icon will give below options as of below diagram.

Click on, Show Development Fabric UI. It will open the UI. This UI will show state of all the instances running for the different types of roles.

Since now only one instance of our application is running, so there is one instance showing in the UI. Let us go back to ServiceConfiguration.csfg
and open this file. Increase number of instance from 1 to 4.

ServiceConfiguration.csfg

<?xml
version=1.0?>

<ServiceConfiguration
serviceName=CloudService1
xmlns=http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration>

<Role
name=WebRole1>


<
Instances
count=4 />

<ConfigurationSettings>

<Setting
name=DiagnosticsConnectionString
value=UseDevelopmentStorage=true />

</ConfigurationSettings>

</Role>

</ServiceConfiguration>

 

Now again open the Development Fabric UI from the tray icon. We can see on clicking of WebRole1, there are 4 instances are running. We could individually manage all the instances of the Web Role.

Step 4

Publishing to cloud (azure)

Right Click on Cloud Service 1 project and select Publish.


It will open the azure site and ask for the login.

If first time, you are login to azure site for publishing browse to account section to redeem your token.

Now either create a project for windows azure or select existing project. I have already a project created with the name of DJProject . I am selecting that.

Since, I have already hosted in the project before. So I am getting the upgrade option. First time, you won’t get upgrade option. First time on creation of Windows azure project it will ask you to give an URL for your project . Just give an URL, which you will use to access your application across.

Click on upgrade option . It will ask for the package file and config file. Browse to CloudService1\bin\publish folder. CloudService1 is name of the application. It may be different in your case , depending on what name you have given in step1.

After uploading package and configuration file , give a label name and click on deploy.

It will take some time for deployment. After successfully deployment you will see a green sign against Web Role saying it is in ready state. You could directly click on Web site URL to test your application on cloud.

Now when you open the URL , you will get the same page as output you got on the local development fabric. And now you successfully hotsed in cloud.

WINDOWS authentication on REST enabled WCF service

Enabling windows authentication on a REST enabled service is relatively easier task than it’s appear. To test that windows authentication is enabled successfully or not use other browser than Internet explorer because IE will automatically do an NTLM negotiation with domain credentials. So when REST service is running in IE, it is not prompting for user credentials.

Service

 A very simple contract as REST service, I am going to use.
Contract

namespace RestserviceWindows{

[ServiceContract]

public interface IService1{
[OperationContract]
[WebGet()]
string GetData();
}}

 Service implementation

namespace RestserviceWindows{

public classService1 : IService1
{
public string GetData(){
return “Testing Windows Authentication with REST service”;
}}}

Configuring the Service

Method #1 Using Factory class

  1. Create a simple REST service. To create a REST service navigates to File->New->Project->Web and select WCF Service Application project template.
  2. WCF will create default endpoints inside System.ServiceModel. Delete both the default endpoints. Delete below end points.
<endpoint address=“” binding=wsHttpBindingcontract=RestserviceWindows.IService1>

<identity>
<dns value=localhost/>
</identity>
</endpoint>
<endpoint address=mexbinding=mexHttpBindingcontract=IMetadataExchange/>

 

  1. Right click on .SVC file. If your service name is Service1 then right click on Service1.svc. After right clicking select View Markup. Add Factory here
<%@
ServiceHost
Language=”C#”
Debug=”true”
Service=”RestserviceWindows.Service1″
CodeBehind=”Service1.svc.cs”
Factory=”System.ServiceModel.Activation.WebServiceHostFactory
%>

 

  1. Host the service in IIS. To host right click on service and Publish in IIS.
  2. Configure IIS for windows authentication.

The above 5 steps are required to host a REST service in IIS with windows authentication.

Method #2 Configuring End Point without Meta Data

  1. Create a simple REST service. To create a REST service navigates to File->New->Project->Web and select WCF Service Application project template.
  2. Delete endpoint address for MEX and binding mexHttpBinding
  3. Configure EndPoint to enable REST service.
  4. Configure EndPoint to enable windows authentication on the service.
  5. Configure End Point behavior.
  6. Make sure, there is no factory class provided for the service in markup of .svc

     

<%@
ServiceHost
Language=”C#”
Debug=”true”
Service=”RestserviceWindows.Service1″
CodeBehind=”Service1.svc.cs” %>

 

  1. Host the service in IIS. To host right click on service and Publish in IIS.
  2. Configure IIS for windows authentication.
<system.serviceModel>

<services>

<service
name=RestserviceWindows.Service1
behaviorConfiguration=RestserviceWindows.Service1Behavior>            

<endpoint
address=“”
binding=webHttpBinding
contract=RestserviceWindows.IService1
bindingConfiguration =RESTBINDING
behaviorConfiguration =REST>

<identity>

<dns
value=localhost/>

</identity>

</endpoint>

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior
name=RestserviceWindows.Service1Behavior>                    

<serviceMetadata
httpGetEnabled=true/>                    

<serviceDebug
includeExceptionDetailInFaults=false/>

</behavior>

</serviceBehaviors>


<
endpointBehaviors>

<behavior
name =REST>

<webHttp/>

</behavior>

</endpointBehaviors>

</behaviors>


<
bindings>

<webHttpBinding>

<binding
name =RESTBINDING>

<security
mode =TransportCredentialOnly>

<transport
clientCredentialType =Windows/>

</security>

</binding>


</
webHttpBinding>

</bindings>

    </system.serviceModel>

 

Method # 3 Configuring End Point with Meta Data

So far in above two methods, Meta Data is not getting exposed. Because mexHttpBinding only supports anonymous binding. So to enable windows authentication on mexHttpBinding , we need to configure IMetaDataContract with some other binding like basicHttpBinding or webHttpBinding.

  1. Create a simple REST service. To create a REST service navigates to File->New->Project->Web and select WCF Service Application project template.
  2. Configure EndPoint to enable REST service.
  3. Configure EndPoint to enable windows authentication on the service.
  4. Configure End Point behavior for both End Points.
  5. Make sure, there is no factory class provided for the service in markup of .svc
<%@
ServiceHost
Language=”C#”
Debug=”true”
Service=”RestserviceWindows.Service1″
CodeBehind=”Service1.svc.cs” %>

 

  1. Host the service in IIS. To host right click on service and Publish in IIS.
  2. Configure IIS for windows authentication.
<system.serviceModel>

        <services>

            <service
name=RestserviceWindows.Service1
behaviorConfiguration=RestserviceWindows.Service1Behavior>                

                <endpoint
address=“”
binding=webHttpBinding
contract=RestserviceWindows.IService1
bindingConfiguration =RESTBINDING
behaviorConfiguration =REST>

                <identity>

<dns
value=localhost/>

</identity>

</endpoint>

                <endpoint
address=mex
binding=webHttpBinding
contract=IMetadataExchange
bindingConfiguration =RESTBINDING/>

            </service>

        </services>

        <behaviors>

            <serviceBehaviors>

                <behavior
name=RestserviceWindows.Service1Behavior>                    

                    <serviceMetadata
httpGetEnabled=true/>                    

                    <serviceDebug
includeExceptionDetailInFaults=false/>

                </behavior>

            </serviceBehaviors>


<
endpointBehaviors>

<behavior
name =REST>

<webHttp/>

</behavior>

</endpointBehaviors>

        </behaviors>

<bindings>

<webHttpBinding>

<binding
name =RESTBINDING>

<security
mode =TransportCredentialOnly>

<transport
clientCredentialType =Windows/>

</security>

</binding>

</webHttpBinding>

</bindings>

    </system.serviceModel>

 

Note: Binding for IMetaDataExchange contract is webHttpBinding.

Consuming the Service

To enable a client to consume a windows authenticated WCF service, client has to pass domain credentials . If HttpClient is used by the client to consume the service then client has to set the credential like

clt.TransportSettings.Credentials=System.Net.CredentialCache.DefaultCredentials;

where clt is instance of HttpClient .

  1. Add Microsoft.Http and System.RunTime.Serlization assembly at refernece
  2. Add namespace of Microsoft.Http and System.Runtime.Serlization
  3. Create insatnce of HttpClint
  4. Set the default credential from the cache.
  5. Perfrom HTTP operation.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Http;

using System.Runtime.Serialization;

using System.Net;

namespace ConsoleApplication1

{

class Program

{
static void Main(string[] args)
{
string url = http://localhost/RESTTESTING/Service1.svc/GetData;

HttpClient clt = new HttpClient();

clt.TransportSettings.Credentials = System.Net.CredentialCache.DefaultCredentials;
HttpResponseMessage msg = clt.Get(url);

string str = msg.Content.ReadAsDataContract<string>();

Console.WriteLine(str);

Console.Read();
}}}

Dynamic Service and End Point Discovery feature of WCF 4.0

This article is 1st part of multi series article on WCF 4.0. This article will list all the new feature of WCF and also will explain in detail Dynamic Service and End Point Discovery feature of WCF 4.0.

What are the new in WCF 4.0?


I am listing here, new features in WCF 4.0

  1. Dynamic Service and End Point discovery
  2. Intermediate Routing Pattern ( Generic Routing Services)
  3. Discovery announcement
  4. Simplified Configuration
  5. Protocol bridging and Fault tolerance
  6. Standard End Points.
  7. .svc-less activation of REST services or making REST URI nice.

Readers Note

I will discuss details of each feature in subsequent articles. This article is emphasizing on Dynamic Service and End Point discovery. So please tune in.

Dynamic Service and End Point discovery

Problem:

People say; you need to know only ABC of a service to expose End Point of that service. And client or service consumer needs to know only End Point to consume the service. But wait for a while here, and think; what if? Binding need to change at the service side from basic to WS over HTTP, This is very basic change but to accommodate this client has to update the service again. And this is very much error prone. It is very tedious task to update client about all the basic frequent change at the service side. To solve this issue, there should be some mechanism and that is called End Point Discovery or Dynamic Service.

In absolute technical words

WCF 4.0 supports WS –Discovery standard or protocol.

WS-Discovery Standard

  1. This is a multicast protocol that issues SOAP message over UDP,
  2. WS-Discovery is a Standard that defines a lightweight discovery mechanism for discovering services based on multicast messages. It enables a service to send a Hello announcement message when it is initialized and a Bye message when is removed from the network.
  3. Client or consumer can discover services by multicasting a Probe message to which a service can reply with a ProbeMatch message containing the information necessary to contact the service.
  4. Client or consumer can find services that have changed endpoint by issuing a Resolve message to which respond with a ResolveMatchmessage.

So, we can say WS –Discovery is a UDP based multicast message exchange. This message receives End Point information from Service and uses this as discovery information. Client uses discovery information to discover the available service on the network.

WCF Service Discovery API

WCF provides, WCF Discovery API for dynamic publish and discovery of web service using WS –Discovery protocol. This API helps service to publish them and helps client to find service on the network.

Modes


Managed Mode

  1. In managed mode there is a centralized server called a discovery proxy that services use to publish themselves and clients use to retrieve information about available services.
  2. When a new service starts up it sends an announcement message to the discovery proxy.
  3. The discovery proxy saves information about each available service to storage.
  4. When a client must search for a service it sends a Probe request to the discovery proxy and it determines whether any of the services that have been published match the request.
  5. If there are matches the discovery proxy sends a ProbeMatch response back to the client.
  6. The client can then contact the service directly using the service information returned from the proxy.

Ad-Hoc Mode

  1. There is no centralized server.
  2. Service announcements and client requests are sent in a multicast fashion.
  3. If a service is configured to send out a Hello announcement on start up, it sends it out over a well-known, multicast address using the UDP protocol.
  4. Therefore, clients have to actively listen for these announcements and process them accordingly.
  5. When a client issues a Probe request for a service it is also sent over the network using a multicast protocol.
  6. Each service that receives the request determines whether it matches the criteria in the Probe request and responds directly to the client with a ProbeMatch message if the service matches the criteria specified in the Probe request.

Sample

In this sample, we will create a very basic service and at the client side, first client will discover the service in Ad-Hoc mode and then consume that.

To run and go through this sample, you need Visual Studio 2010 Beta.

To make a service discoverable, a ServiceDiscoveryBehavior must be added to the service host and a discovery endpoint must be added to specify where to listen for and send discovery message

Step1

Open VS2010. Create a new project. Select project type as Web. From Web Project type choose WCF Service Application Project template

Step 2

Delete all the code which is generated by Visual studio. After deleting Contract and Service Implantation is as follows.

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 WcfService1

{

[ServiceContract]


public
interface
IService1

{

[OperationContract]


string GetMessage(string msg);

}

}

 

Service1.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 WcfService1

{


public
class
Service1 : IService1

{


public
string GetMessage(string msg)

{


return msg;

}

}

}

 

The above is simple Service Contract and implantation of that.

Step3

Open Web.Config file. And modify the System.ServiceModel. Add the code which in red rectangle below.

Web.Config

<system.serviceModel>

<services>

<service
name=WcfService1.Service1
behaviorConfiguration=WcfService1.Service1Behavior>

<!– Service Endpoints –>

<endpoint
address=“”
binding=wsHttpBinding
contract=WcfService1.IService1>

<!–

Upon deployment, the following identity element should be removed or replaced to reflect the

identity under which the deployed service runs. If removed, WCF will infer an appropriate identity

automatically.


–>

<identity>

<dns
value=localhost/>

</identity>

</endpoint>

<endpoint
name =udpDiscovery
kind =udpDiscoveryEndpoint />

<endpoint
address=mex
binding=mexHttpBinding
contract=IMetadataExchange/>

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior
name=WcfService1.Service1Behavior>

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

<serviceDiscovery />

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

 

Explanation of Config file

  1. One new End Point is being added.
  2. Kind of newly added End Point is udpDiscoveryEndpoint.
  3. This End Point will be used to discover the service.
  4. ServiceDiscovery behavior is also get added.

 

Press F5 to run the service. Service will get hosted in ASP.Net web server.


Step 4

Add a new console project in solution. Add Reference of System.ServiceModel.Discovery.dll in console project.


Step 5

Add namespace using System.ServiceModel.Discovery;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

using System.ServiceModel;

using System.ServiceModel.Discovery;

namespace ConsoleApplication1

{


class
Program

{


static
void Main(string[] args)

{


DiscoveryClient discoverclient = new
DiscoveryClient(new
UdpDiscoveryEndpoint());


FindResponse response = discoverclient.Find(new
FindCriteria(typeof(IService1)));


EndpointAddress address = response.Endpoints[0].Address;


Service1Client client = new
Service1Client(new
WSHttpBinding(), address);


string str= client.GetMessage(“Hello WCF 4 “);


Console.WriteLine(str);


Console.ReadKey(true);

}

}

}


 

 

Explanation of the code

  1. We are making object of DiscoveryClient class. This class is user to discover available service.
  2. In constructor of this class, we are passing UdpDiscoveryEndPoint of the service.
  3. Then we are calling Find method with contract name as argument to get FindResponse.
  4. Now FindResponse variable having all the available address for contract passed in Find method.
  5. We are creating the client proxy and passing discovered address as argument.
  6. Calling the service operation on the client proxy.

Output


Conclusion

In this article, I talked about what are the new features in WCF 4.0. I went into details of Dynamic Service and End Point Discovery. In later articles, I will cover in detail other features as well. Till then, thanks for reading.

Rich Text Box in Silver Light 4.0

Objective

In this article, I am going to show how to work with Rich Text box in Silver Light 4.0. I will show how to inline buttons and image inside rich text box. How to make text box as read only. How to change font of selected text. I have created a basic Silver Light page and it contains

  1. One Grid with two rows.
  2. First row is having one button and one checkbox.
  3. Purpose of button is to bold the selected text.
  4. Checkbox is to make rich text box read only.

Xaml is as below,

<UserControl x:Class=”RichTextBoxdemo2.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”


d:DesignHeight=”300″ d:DesignWidth=”400″>

 </Grid.RowDefinitions>
<StackPanel Orientation=”Horizontal” Grid.Row=”0″ Background=”Blue” >
<CheckBox x:Name=”chkReadOnly” IsChecked=”False” Width=”100″ Height=”auto” VerticalAlignment=”Bottom Content=”ReadOnly”/>
<Button x:Name=”btnBold” Content=”Bold” Click=”btnBold_Click” Width=”100″ Height=”auto” HorizontalAlignment=”Left” VerticalAlignment=”Bottom” Margin=”10,2,2,2″ />
</StackPanel>
<RichTextArea Grid.Row=”1″ VerticalAlignment=”Stretch” HorizontalAlignment=”Stretch” IsReadOnly=”False” TextWrapping=”Wrap”>
</RichTextArea>
</Grid></UserControl>


<Grid x:Name=”LayoutRoot” Background=”White”>

<Grid.RowDefinitions>

<RowDefinition Height=”1*”/>

<RowDefinition Height=”7*” />

Output of above Xaml


Paragraph in Rich Text Box

Now, I will start adding paragraph in the rich textbox. We can add as many paragraphs as we want in Rich text box.

<Paragraph x:Name=”HeadPara” TextAlignment=”Center” FontSize=”42″
FontFamily=”Georgia”> This is Rich Text Demo
</Paragraph>

 New Line in Rich Text Box
Now, we can use new line or line break in side paragraph of a rich text box.

<LineBreak />

 In Line Container in Rich Text Box
We can have as many other UI elements inside rich text box as we want. We need to put UI elements inside paragraph and inside paragraph inside InLIne container. In below sample I have two UI element one button and image inside a rich text box.

<Paragraph x:Name=”ps”> <InlineUIContainer >
<Image x:Name=”imageinText” Height=”150″ Width=”100″ Source=”a.jpg”/>
</InlineUIContainer>
<InlineUIContainer>
<Button x:Name=”inlinebtn” Click=”inlinebtn_Click” Height=”60″ Width=”100″ Content=”InLine Button”  Background=”Brown” />
</InlineUIContainer>
</Paragraph>

Note: UI element will be active only when text box is read only. What I mean is, let us say you have a click event on button inside rich text box. This click event will only work when text box is read only.

MainPage.Xaml

<UserControl x:Class=”RichTextBoxdemo2.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”
 d:DesignHeight=”300″ d:DesignWidth=”400″>
<Grid x:Name=”LayoutRoot” Background=”White”>
<Grid.RowDefinitions>
<RowDefinition Height=”1*”/>
<RowDefinition Height=”7*” />
</Grid.RowDefinitions>
<StackPanel Orientation=”Horizontal” Grid.Row=”0″ Background=”Blue” >
<CheckBox x:Name=”chkReadOnly” IsChecked=”False” Width=”100″ Height=”auto” VerticalAlignment=”Bottom”
Content=”ReadOnly” Click=”chkReadOnly_Click”/>
<Button x:Name=”btnBold” Content=”Bold” Click=”btnBold_Click” Width=”100″ Height=”auto” HorizontalAlignment=”Left” VerticalAlignment=”Bottom” Margin=”10,2,2,2″ />
</StackPanel>
<RichTextArea x:Name=”rchTxt” Grid.Row =”1″ VerticalAlignment=”Stretch” HorizontalAlignment=”Stretch” IsReadOnly=”False” TextWrapping=”Wrap”>
<Paragraph x:Name=”HeadPara” TextAlignment=”Center” FontSize=”42″ FontFamily=”Georgia” >

 This is Rich Text Demo
</Paragraph>
<Paragraph x:Name=”rightpara” TextAlignment=”Right” FontSize=”18″>

 This is right
<LineBreak />
text for you
<LineBreak />
<Italic> See I am Italic</Italic>
</Paragraph>
<Paragraph x:Name=”ps”>
<InlineUIContainer >
<Image x:Name=”imageinText” Height=”150″ Width=”100″ Source=”a.jpg”/>
</InlineUIContainer>
<InlineUIContainer>
<Button x:Name=”inlinebtn” Click=”inlinebtn_Click” Height=”60″ Width=”100″ Content=”InLine Button Background=”Brown” />
</InlineUIContainer>
</Paragraph>
</RichTextArea>
</Grid></UserControl>

 Making selected text Bold

Set the property value to bold for selected text.

private void btnBold_Click(object sender, RoutedEventArgs e){if (!String.IsNullOrEmpty(rchTxt.Selection.Text)){
rchTxt.Selection.SetPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
}}

 On Inline button click calling the message box


private void inlinebtn_Click(object sender, RoutedEventArgs e)MessageBox.Show(“I have been clicked from In Line button in Rich text box”);}

{

 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;

namespace RichTextBoxdemo2{
public partial class MainPage : UserControl{
public MainPage(){
InitializeComponent();
rchTxt.IsReadOnly = false;}
private void btnBold_Click(object sender, RoutedEventArgs e){
if (!String.IsNullOrEmpty(rchTxt.Selection.Text)){
rchTxt.Selection.SetPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
}}
private void inlinebtn_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(“I have been clicked from In Line button in Rich text box”);
}
private void chkReadOnly_Click(object sender, RoutedEventArgs e)
{
CheckBox S = (CheckBox)sender as CheckBox;
rchTxt.IsReadOnly = S.IsChecked == true;
}}}

Output


When only check box read is checked then inline button click event will work as