Sunday, July 13, 2008

Message Contracts Vs Data Contracts in WCF

There's a big confusion among WCF developers while understanding the concept of Message Contracts. Are they really required? Why were they included in WCF when Data Contracts can do everything.

Well the truth is that both Message Contracts and Data Contracts possess their own niche in SOAP messaging. In the below table, I'll be drawing a thick line to show differences between Message Contracts and Data Contracts

Data Contracts Message Contracts
Data Contracts primarily target the XSD schema definitions of Soap Messages Message Contracts primarily target the <soap:Header> and <soap:Body> construction
Data Contracts can control only the contents of Soap message data. Just the types between the <soap:Body> section Message Contracts can control the whole SOAP message
Data Contracts are mostly used while dealing with serialized types within the message body Message Contracts are mostly used while passing security information as tokens, correlation guids into the soap headers
Data contracts take care of the Data Structures of the message e.g. defining complex types, collections, etc Message Contracts take care of the overall message structure of the WSDL

 


Multiple interfaces in a WCF contract

Well most of the time we have requirement of having one ServiceContract for an endpoint. But sometimes we get into a situation when the implementation is spread across multiple interfaces and we need to include the functionality spread into both the implementations into our WCF class. To suffice such a requirement we can use the concept of Interface Aggregation. Suppose we have two interfaces
  • ITemperature
  • IRainfall

The former returns the temperature of a particular location and the latter returns rainfall measure. Now suppose we have another interface called IWeather which will hold the functionality of returning weather forecast. The below code shows how to achieve this functionality using C#

namespace AggregatedContracts{
[ServiceContract]
public interface ITemperature
{
[OperationContract]
double GetTemperature(double latitude, double longitude);
}

[ServiceContract]
public interface IRainfall
{
[OperationContract]
double GetRainfall(double latitude, double longitude);
}

ServiceContract]
public interface IWeather : ITemperature,IRainfall{};
{
[OperationContract]
string GetWeatherForecast(double latitude, double longitude);
}

public class WeatherInfo : IWeather{
//implement ITemperature


//implement IRainfall
}
}






Saturday, July 12, 2008

IIS hosted Duplex WCF Service

Today, I'm showing you how to create a Duplex Contract WCF service which will be hosted in the IIS and called from various console App clients. We will be understanding the WCF Duplex Services and Contracts concept from the classic Stock Exchange example. In this example we are having a WCF Duplex service named DuplexStock1. This service will receive subscription requests from various clients for a stock tickers like MSFT, YAHOO, etc.

The WCF Service will create separate threads for each client connecting to it (Though its not quite optimized approach,but simple to explain here). The service will push the stock values to the cilents through Duplex channe periodically (after 5 seconds). Stock values are randomly updated from 0 to 100 and pushed to the client.

The clients will show the updated stock values for the subscribed ticker in their Console Window. The main of this blog post is not explain each and every concept of Duplex Binding but to show a working example.

Lets commence by creating the Server..




namespace StockMarketServer
{
[ServiceContract(CallbackContract=typeof(IClientCallback1))]
public interface IDuplexStock1
{
[OperationContract(IsOneWay = true)]
void SubscribeForStockUpdate(string strTicker);
}

public interface IClientCallback1
{
[OperationContract(IsOneWay=true)]
void UpdatePrice(string ticker, double price);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class DuplexStock1 : IDuplexStock1
{
public void SubscribeForStockUpdate(string strTicker)
{
Update objUpdate = new Update();
objUpdate._ticker = strTicker;
objUpdate.callback = OperationContext.Current.GetCallbackChannel();
Thread t = new Thread(new ThreadStart(objUpdate.SendUpdateToClient));
t.IsBackground = true;
t.Start();
}
}
public class Update
{
public IClientCallback1 callback=null;
public string _ticker;
public void SendUpdateToClient()
{
Random rnd= new Random();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(5000);
try
{
callback.UpdatePrice(_ticker, rnd.NextDouble() * 100.0);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
}


As you can see in the above code we have two interfaces one for WCF Service Contract [IDuplexStock1]other for the client [IClientCallback1]. The SubscribeForStockUpdate method is invoked by every client when it wants to subscribe for a particular stock ticker update. The service gets the client channel in which to push the updates using the GetCallbackChannel method can spawns a new thread with Update class. This class starts pushing data to client randomly.



Now lets see the WCF service configuration which will help it to be hosted in IIS
































Put the above code in Web.config of your WCF project and make the project folder as the virtual directory. If you have done everything alright, then you should be able to see service metadata when you browse the baseAddress Url in the browser.



Now lets start building the Console Application Clients. Start by adding a console application project to your solution. Then use "Add Service reference" and give the above baseAddress Url. This will create WSDL proxies and put client configuration into the app.config your ConsoleApp. Here's what your console App's app.config should look like







...blah..blah..>
maxBytesPerRead="4096" maxNameTableCharCount="16384" />


algorithmSuite="Default" />





binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IDuplexStock1"
contract="StockMarketServerProxy.IDuplexStock1" name="WSDualHttpBinding_IDuplexStock1">










Ensure that the bolded tags shown above are present in your app.config. They are the key pillars to support Duplex Communication. Now finally lets start coding the client console app




namespace StockMarketConsoleClient
{
class Program
{
static InstanceContext site = new InstanceContext(new CallbackHandler());
static DuplexStock1Client objDupCl = new DuplexStock1Client(site);
public Program()
{
try
{
Console.Write("Input Stock ticker::");
string strInputTicker=Console.ReadLine();
objDupCl.SubscribeForStockUpdate(strInputTicker);
Console.WriteLine("Server connection established, wait for updates to be pushed by the server...");
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine("Exception ::" + ex.Message);
Console.Read();
}
}
static void Main(string[] args)
{
Program objPr = new Program();
}
}

public class CallbackHandler : IDuplexStock1Callback
{

public void UpdatePrice(string ticker, double price)
{
Console.WriteLine("Recieved push for ticker :: " + ticker + " value is " + price.ToString() + " on " + DateTime.Now.ToString());
}
}
}







Wednesday, July 9, 2008

WCF bare unwrapped Response

Many times we have seen that a WCF method of return type string spits Response which is wrapped in a String element e.g. the one shown below

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
<Company>Nucleus</Company></string>

We may want it to return pure Xml Response, the unwrapped one like

<Company>Nucleus</Company>

These are steps you should use to achieve it

1. Change the webmethod return type from string to System.IO.Stream
2. Remove any BodyStype property from its attributes because even the barest BodyStyle will return wrapped response.
3. Return a Stream instead of string from your webmethod. This can be done with the following simple code
return new MemoryStream(Encoding.UTF8.GetBytes(strRetXml));

Differences between WPF and Silverlight

Nowadays, two terms are mostly heard in Windows Graphics sphere, WPF and Silverlight. Many of us presume they are one and the same thing. But actually there are fundamental differences between the two. In this post, I'm posting the basic differences between the two (primarily Silverlight 1.x)
WPFSilverlight 1.x
WPF is the complete graphics framework written from the scratch by MicrosoftSilverlight is subset of WPF in the sense that it contains only windows independent class libraries of WPF
WPF applications are not Web enabled. They are mostly focused around Windows FormsSilverlight has been introduced for the sole purpose of enabling Web support for WPF applications
WPF applications are supported by only Windows based computersSilverlight provides support for different browsers like Firefox and Safari
WPF applications whole heartily support and use C#Silverlight applications use XAML and Javascript to define their markup and behaviour. C# code is not supported
WPF requires .NET runtimeSilverlight doesn't require .NET runtime to render its graphics
WPF uses Windows media player on the client to play any mediaSilverlight uses OS media support to play media
WPF has capability to create 3D graphicsSilverlight is limited to 2D graphics only

Resolving Download Failure in WebClient

Today I was developing a Silverlight client program which reads cross-domain content when I started facing Download Failure exception. This is code I was using, which resulted in exception

private void btnSearch_Click(object sender, RoutedEventArgs e){
string strTopic=txtSearchTopic.Text;
string strUrl = "";
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler
(this.DownloadCompleted);
wc.DownloadStringAsync(new Uri(strUrl));
}
private void DownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
string strResult = e.Result;
}
}


So in this code, Line 10 was throwing Download failure exception probably because my domain in not registered in GroupPolicy.xml file on the server from which I was reading the content. Now the solution to this problem is to use System.Net.HttpWebRequest object which can easily read data across domains. So here are steps:

  • Add Reference to System.Net assembly


  • Add System.Net namespace and replace the previous code with this code





private void btnSearch_Click(object sender, RoutedEventArgs e)
{
string strTopic = txtSearchTopic.Text;
string strUrl = "";
HttpWebRequest objRq = (HttpWebRequest)WebRequest.Create(new Uri(strUrl));

objRq.BeginGetResponse(new AsyncCallback(responseHandler), objRq);

}
void responseHandler(IAsyncResult asyncResult)
{
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
Stream respStream = response.GetResponseStream();
if (respStream != null)
{
StreamReader sr = new StreamReader(respStream);
//Here you will get the content in strResp string
string strResp = sr.ReadToEnd();

}
}




And the above code worked.





Silverlight HyperlinkButton turns page blank

Today when I was using the HyperlinkButton control on a Silverlight page and supplying it proper values for NavigateUri and Content attributes, I found that the control was not behaving properly and made the page blank while rendering in the browser.

It threw browser exception saying InvalidOperationException. This was the code which I was using

<HyperlinkButton x:Name=”lnkSports” Content="Sports Page"

NavigateUri="http://easports.com" Grid.Row="0" Grid.Column="1"/>

It happens because HyperlinkButton expects its NavigateUri property to be of type System.Uri rather than System.String


lnkSports.NavigateUri=new Uri("http://easports.com");

So a simple creation of Uri object in the code behind helped to solve this problem as shown above

Handle Silverlight event in javascript

This post will show you how to throw events from Silverlight controls in managed code and catch them in javascript. Such a scenario comes while building HTML bridge in Beta 2, when you need to catch the events from Silverlight UserControls in the aspx page hosting them. We'll take the example of ListBox SelectionChanged Event. Whenever Listbox's selection is changed in the SL user control we'll show an alert on javascript which is having that SelectedText from the Listbox. Firstly the UserControl say UserControl1 which will throw the event, needs to have an event and a property marked with ScriptableMemberAttribute which is found under System.Windows.Browser. So here is how you add Scriptable members

private string _selectedText;
[ScriptableMemberAttribute]
public string SelectedText{
get{
return _selectedText;
}
}
[ScriptableMemberAttribute]
public event EventHandler MySelectionChanged;



Then we'll add the code the update the SelectedText property whenever ListBox selection is changed



private void lstMaster_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_selectedText= lstMaster.SelectedItem.ToString();
if (MySelectionChanged != null)
{
MySelectionChanged(sender,e);
}
}



The above code also raises the event which will be caught in JS

After this you need to register UserControl1 in the App.xaml file so that it available to the host aspx page's javascript. This is code you need to write for that

private void Application_Startup(object sender, StartupEventArgs e)
{
UserControl1 objPage = new UserControl1();
HtmlPage.RegisterScriptableObject("registerPage", objPage);
}


Then finally we'll register an event handler for our custom event to a javascript method. This is done by on the OnPluginLoaded attribute of the <asp:Silverlight> control tag. Here's the code for that


//Adding javascript event listener
function hookEvent(sender){
var UC=sender.get_element();
UC.Content.registerPage.addEventListener("MySelectionChanged",jsEventHandler);
}

function jsEventHandler(sender,args){
var UC=document.getElementById("Xaml1");
alert( UC.Content.registerPage.SelectedText);
}



Essential XAML Simplified 2

As we have seen in the previous post XAML provides new generation of opportunities by which we can describe an object. Here we'll cover the remaining two concepts

  • Attached Properties
  • Markup Extensions

Going back to previous example of TextBlock which is shown below

<TextBlock Text="Title:" Style="{StaticResource TextBlockStyle}"

Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right"></TextBlock>

Attached Properties refers to the ability by which child objects can set properties of parent object. In this control Grid (parent control) contains this TextBlock (child control). The way it helps is child elements inform the parent element of how they are to be presented in the user interface (UI). Another possiblity is different child elements unique values for the same parent element depending their own suitability. A point not be missed here is that a control which sports Attached Properties should implement them as Dependency properties in it own definition.

Alright! Markup Extensions.

Basically it refers to the attribute value being picked up from a collection which is described elsewhere. In the above example the Collection of StaticResource(s) can be put inside App.xaml (which is common markup for all your applications in the assembly) like this

<Application.Resources>

<Style x:Key="TextBlockStyle" TargetType="TextBlock">

<Setter Property="ForeGround" Value="Black"></Setter>

<Setter Property="Margin" Value="2"></Setter>

</Style></Application.Resources>

Similar we can have a Binding Markup like

Text="{Binding QuantityOnHand}"

where QuantityOnHand is column in an IEnumerable collection.

Monday, July 7, 2008

ProtocolException 404 Silverlight WCF

This is blog entry will help those who understand Cross Domain restrictions in Silverlight while calling a WCF service in another domain. If you already tried many prescribed things to allow Cross Domain Access like placing the clientaccesspolicy.xml in wwwroot folder and putting a crossdomain.xml on the IIS root (wwwroot folder). But still you are getting the same obstinate 404 error. Then you can try these two tricks which worked for me

1. Firstly make sure the you restart IIS whenever you create new policy files or update them.

2. Make sure that you SL client is an aspx page not HTML page (because aspx page runs in worker process account, somehow html doesn't work for some people)

3. Try changing this line in your clientaccesspolicy.xml

From :

<allow-from>
<domain uri="*"/>
</allow-from>

To:

<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>

These tricks worked for me and I wish they work for you also :)

Saturday, July 5, 2008

Step into WCF service

This article addresses a common problem encountered while debugging a WCF service hosted in IIS from a client like a Console App or a Win App. Even if you put break points in the WCF service but you are not able to step into the service by pressing F11. Instead you a get an error dialog as show below saying

"Unable to automatically step into the server. The remote procedure could not be debugged..."

excp_diag

I faced the same situation and was able get the Step In working by confirming the below conditions in my project

1. Making sure the WCF Service is complied in "Debug" mode

2. Making sure that Web.config or App.config of the WCF service contains this entry

<system.web>
<compilation debug="true" />
</system.web>

Happy debugging!

Thursday, July 3, 2008

How to read post request in WCF

Sometimes we have requirement in which we have to read data from request body / payload instead of its Querystring. Though it can be easily done in .NET 2.0 but it is hard to find in WCF. In this post, we'll see how to do it.

Here's the code to perform this


//Code Listing 1
public void MyPostHandler(Stream input){
StreamReader sr = new StreamReader(input);
string str = sr.ReadToEnd();
sr.Close();//str will contain the body payload of POST request
}

MyPostHandler method should be decorated with the WebInvoke attribute to handle Post requests. This is how it is done


//Code Listing 2
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "*")]
void MyPostHandler(Stream input);

So in the Code Listing 1 we see how raw request body was read into a string using the input Stream from which it arrived to the WCF service hosted in IIS

Why REST is called Representational State Transfer?

The extension of the acronym REST is Representational State Transfer. This extension was wisely chosen by Roy Fielding because it says a lot in just three words. Many of us might have wondered why REST is called so?

So here's a small explanation based on My Understanding

The definition goes back in 1990s when REST was being invented and Web was a very nascent creature.

The word Representational pertains to the representation of a resource. As we know a resource is quite centric to REST and is represented by a URI.

The word State Transfer comes from the concept of state machines. A well architected REST website is regarded as virtual state machine. Using links to move from one page (resource) to another is regarded as state transitions.

e.g. When the client is accessing page 1 of REST website through URI 1 he is considered in State 1. When he moves to linked page 2 which contains URI 2 on that website, he's considered transferred from State 1 to State 2.

That's how all this philosophy comes through. After all Roy Fielding submitted this masterpiece in his PhD Dissertation in 2000.

Wednesday, July 2, 2008

Adding multiple Silverlight user controls on aspx

Sometimes we have requirement of adding multiple Silverlight UserControls over same ASP.NET web page (aspx). Like when you want to host silverlight web parts on a single aspx page in separate areas.
All silverlight controls are zipped into a single .xap file. And the tag refers to xap file using source attribute as shown in the below code
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/MySLapp.xap" />
The App.xaml file contains the Application_Startup event which contains the information about the starting user control which will be rendered when the silverlight xaml is consumed by the browser. We can manipulate the InitParams property of this method to dynamically set the starting user control for the silverlight application. The below method shows how can we achieve the requirement of calling different user controls from the same aspx page.

Firstly set the different user controls on the aspx page as shown below

<asp:Silverlight ID="Xaml1" InitParameters="ControlId=1" runat="server" Source="~/ClientBin/MySLapp.xap" />
<asp:Silverlight ID="Xaml2" InitParameters="ControlId=2" runat="server" Source="~/ClientBin/MySLapp.xap" />
Next, you can dynamically set the user control to be rendered by the application using this logic
private void Application_Startup(object sender, StartupEventArgs e)
{
if (e.InitParams.ContainsKey("ControlId"))
{
if (e.InitParams["ControlId"] == "1" )
this.RootVisual = new UserControl1();
else
this.RootVisual = new UserControl2();
}
}

where UserControl1 and UserControl are you Silverlight UserControls.



Read XML into string using LINQ

LINQ has made programmer’s life much easier and taken away pains of parsing XML nodes using XPath or Xml DOM. In this thread, we’ll see an example of reading XML contents into string variables using LINQ. Suppose we have sample XML Message which looks like this

<Input>

<City>Ludhiana</City>

<State>Punjab</State>

<Country>India</Country>

<Phone>01613535366</Phone>

</Input>


Now you want to parse the contents of these XML elements and retrieve them into various string objects. Next code is exactly to serve this purpose


//include these namespaces
using System.Xml;
using System.Linq;
using System.Xml.Linq;
using System.IO;

//real code to read strings
string xml = "..xml above as a string..";
TextReader tr = new StringReader(xml);
XDocument xmlDoc = XDocument.Load(tr);
XElement inputXmlElement = xmlDoc.Element("Input");
string city = (string) inputXmlElement.Element("City");
string state = (string) inputXmlElement.Element("State");
string country = (string) inputXmlElement.Element("Country");
string phone = (string) inputXmlElement.Element("Phone");

You can notice, how dramatically the lines of Code has decreased.

Note: For using LINQ in VS 2005 you have some prerequisites i.e. you need to install LINQ extensions first.

InitializeFromXaml & XamlReader.Load in Silverlight Beta 2

In this post, we’ll discuss how to resolve two common issues which come while migrating Silverlight Beta 1 Apps to Beta 2. Below I am showing Beta 1 code and its equivalent code in Beta 2
Compile time error1. Does not contain a definition for InitializeFromXaml


//Beta 1
System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream("MyNamespace.UserControl1.xaml");
FrameworkElement control = this.InitializeFromXaml(new System.IO.StreamReader(s).ReadToEnd());



//Beta 2
Application.LoadComponent(control, new Uri("
;component/.xaml", UriKind.Relative));

OR


//Beta 2
System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream("MyNamespace.UserControl1.xaml");
FrameworkElement control = XamlReader.Load(new System.IO.StreamReader(s).ReadToEnd()) as Control;

Please note that <projectname> should be replaced by the VS 2008 project name or assembly dll name. component is a constant word and <classname> should be replaced by your .NET Class name of the User Control

Compile time error
2. No overload for method Load takes 2 arguments


//Beta 1
XamlReader.Load(string,boolean)

This function parses a well-formed XAML fragment and creates a corresponding Silverlight object tree, and returns the root of the object tree.


//Beta 2
XamlReader.Load(string)

Allow PUT in IIS

I was having a WCF webservice which was supposed to be called via HTTP PUT method. I wrote my PUT method handlers using REST support in WCF ie WebInvoke(method="POST") and was hoping that things will go smooth. But suddenly I started getting 403 forbidden errors from IIS whenever I started making requests to this service using Fiddler.

I ensured that IIS is having “Scripts and Executables” permission on the Virtual Directory which hosted the service and Worker Process user was having full rights on the Folder where service is present. What else does the IIS require?

Finally after doing some research, I found out the PUT requests are served by WebDAV in IIS 6.0. So first thing I did was to enable WebDAV service extension in IIS by setting it to “Allowed” from “Prohibited” as shown below








Next I found that I have to allow PUT verb for the .svc extension in the IIS configuration. This is how it is done.

1.Right click Virutal Directory
2.Goto Properties and click on Configuration button
3.Select .svc extension from the Application Extensions list
4.Append the PUT verb to the list of allowed verbs for this extension as shown in the figure below









That was it and my service was getting hit now.

Non-postback dropdownlist using AJAX

In this article, we’ll use the excellence of AJAX to create a non-postback dropdownlist which pulls its data from the server without refreshing entire page. Primarily, we will leverage the core functionality of the UpdatePanel ASP.NET AJAX control which makes it possible.
I have kept this article developer friendly which means you don’t need to write much Javascript and will be writing .NET code only, which you love.
So today we’ll be creating dependent dropdownlist which pulls out Cities for a State. We’ll have 2 dropdownlists
1. ddlState - which shows Indian States
2. ddlCity - which contains cities in those states
To start with create a project in VS.NET using ASP.NET AJAX template because it enters information regarding AJAX extensions into your web.config. Put these code elements into your aspx

<form id=”form1″ runat=”server”>

<div>

<asp:ScriptManager ID=”ScriptManager1″ runat=”server”>

</asp:ScriptManager>

<asp:UpdatePanel ID=”up1″ runat=”server”>

<ContentTemplate>

<table border=”0″>

<tr>

<td>

State :

</td>

<td>

<asp:DropDownList ID=”ddlState” runat=”server”

OnSelectedIndexChanged=”ddlState_SelectedIndexChanged”

AutoPostBack=”true”>

<asp:ListItem Text=”Andhra” Selected=”True”></asp:ListItem>

<asp:ListItem Text=”Punjab”></asp:ListItem>

<asp:ListItem Text=”Karnataka”></asp:ListItem>

</asp:DropDownList>

</td>

</tr>

<tr>

<td>

Cities :

</td>

<td>

<asp:DropDownList ID=”ddlCity” runat=”server”>

</asp:DropDownList>

</td>

</tr>

</table>

</ContentTemplate>

</asp:UpdatePanel>

</div>

</form>

And this is how your code behind should look like

protected void ddlState_SelectedIndexChanged(object sender, EventArgs e)
{
ddlCity.Items.Clear();
if (ddlState.SelectedValue == “Punjab”)
{
ddlCity.Items.Add(new ListItem(“Ludhiana”));
ddlCity.Items.Add(new ListItem(“Mohali”));
ddlCity.Items.Add(new ListItem(“Amritsar”));
}
else if (ddlState.SelectedValue == “Andhra”)
{
ddlCity.Items.Add(new ListItem(“Hyderabad”));
ddlCity.Items.Add(new ListItem(“Vijaywada”));
ddlCity.Items.Add(new ListItem(“Warangal”));
}

else if (ddlState.SelectedValue == “Karnataka”)
{
ddlCity.Items.Add(new ListItem(“Bangalore”));
ddlCity.Items.Add(new ListItem(“Mangalore”));
ddlCity.Items.Add(new ListItem(“Mysore”));
}
}

You can run and test the application by selecting different values from the State combo box and noting that City list is populated by the server without refreshing the entire page. This is how your page should look like in the output

Difference between WCF Service Reference and Web Reference

Previously, I wrote a post about Adding Service Reference in VS 2008. Adding Web Reference has been deprecated in VS 2008, as Microsoft now wants to promote WCF's Add Service Reference only. In this post we'll see basic differences in client proxy which have implemented Add Web Reference ( AWR ) and Add Service Reference ( ASR )

First difference is that to create AWR resources (proxy class and config) in WCF client you use wsdl.exe, whereas for ASR you use svcutil.exe

Now Imagine you have ASMX service

http://www.blogger.com/post-edit.g?blogID=2403430606101974989&postID=2436002957902424313#

whose reference you added onto a WCF client using AWR. So its app.config will look like the one below


<Consoleapp.Properties.Settings>
<setting name="ConsoleApp_MySvc_MyService" serializeAs="String">
<value>http://localhost/WCFWeb/MyService.asmx</value>
</setting>
</Consoleapp>


Now if you Add Service Reference of the same ASMX service on the same client, the app.config will look something like this


<endpoint address="http://localhost/WCFWeb/MyService.asmx"
binding="basicHttpBinding" bindingConfiguration="ServiceSoap"
contract="ASMXRef.ServiceSoap" name="ServiceSoap"/>

<binding name="ServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8"
transferMode="Buffered" useDefaultWebProxy="true">

<readerquotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"
/>

<security mode="None">

<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />

<message clientCredentialType="UserName" algorithmSuite="Default" />

</security>

</binding>


So you can clearly note how ASR register additional level of detail like Bindings, Commincation parameters, transport security and message security info. Whereas AWR just registers a app.config key. This is difference between ASR and AWR from configuration information point.