Posts Tagged WWF

Syndication in WCF –

Posted by admin on Friday, 11 February, 2011

Syndication

By publishing the service results in either RSS 2.0 or Atom 1.0 format, your customers get automatic notifications whenever there is some change in the output.

  1. Create a new WCF Service Library and name it as ‘TemperatureServiceLibrary’.
  2. Rename the default service interface and service implementation files as ‘ITemperatureService.cs’ and ‘TemperatureService.cs’.
  3. Open ‘ITemperatureService.cs’ and modify the code to look like the one below.

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.ServiceModel.Syndication;

namespace TemperatureServiceLibrary

{

[ServiceContract]

[ServiceKnownType(typeof(Atom10FeedFormatter))]

[ServiceKnownType(typeof(Rss20FeedFormatter))]

public interface ITemperatureService

{

[OperationContract]

[WebGet(

UriTemplate = "GetForecast/{format}")]

SyndicationFeedFormatter GetForecast(string format);

//Atom10FeedFormatter GetForecast();

//Rss20FeedFormatter GetForecast();

}

[DataContract(Name = "Forecast", Namespace = "")]

public class Forecast

{

[DataMember(Name = "City")]

public string City { get; set; }

[DataMember(Name = "Day1LowTemp")]

public double Day1LowTemp { get; set; }

[DataMember(Name = "Day1HighTemp")]

public int Day1HighTemp { get; set; }

[DataMember(Name = "Day1Details")]

public string Day1Details { get; set; }

[DataMember(Name = "Day2LowTemp")]

public int Day2LowTemp { get; set; }

[DataMember(Name = "Day2HighTemp")]

public int Day2HighTemp { get; set; }

[DataMember(Name = "Day2Details")]

public string Day2Details { get; set; }

}

}

  1. Put the following code into TemperatureService.cs

using System;

using System.Collections.Generic;

using System.ServiceModel.Syndication;

namespace TemperatureServiceLibrary

{

public class TemperatureService : ITemperatureService

{

#region ITemperatureService Members

//public Rss20FeedFormatter GetForecast()   //–Use this signature if you just want to emit RSS 2.0

//public Atom10FeedFormatter GetForecast()  //–Use this signature if you just want to emit Atom 1.0

public SyndicationFeedFormatter GetForecast(string format)

{

var feed = new SyndicationFeed();

feed.Title = new TextSyndicationContent(

“Eden Prairie Weather Forecast”);

feed.Authors.Add(new SyndicationPerson(

“weather@appdev.com”));

feed.Categories.Add(

new SyndicationCategory(“Weather Forecasts”));

feed.Description = new TextSyndicationContent(

“This is the weather forecast for Eden Prairie”);

var randomNumber = new Random();

var items = new List<SyndicationItem>();

var item = new SyndicationItem(“Day 1 Forecast”,

String.Format(“Cold, windy, snowy. ” +

“Low of {0}. High of {1}.”,

randomNumber.Next(20, 30).ToString(),

randomNumber.Next(30, 40).ToString()),

new Uri(“http://www.mysite.com”),

“Today”, DateTime.Now);

items.Add(item);

item = new SyndicationItem(“Day 2 Forecast”,

String.Format(“Colder, windier, snowier. ” +

“Low of {0}. High of {1}.”,

randomNumber.Next(10, 20).ToString(),

randomNumber.Next(20, 30).ToString()),

new Uri(“http://www.mysite.com”),

“Tomorrow”, DateTime.Now);

items.Add(item);

item = new SyndicationItem(“Day 3 Forecast”,

String.Format(“blah. blah. blah. ” +

“Low of {0}. High of {1}.”,

randomNumber.Next(15, 25).ToString(),

randomNumber.Next(30, 40).ToString()),

new Uri(“http://www.envirnment.com”),

“Day After”, DateTime.Now);

items.Add(item);

feed.Items = items;

//return new Rss20FeedFormatter(feed);    //–Uncomment this to emit RSS 2.0

//return new Atom10FeedFormatter(feed);   //–Uncomment this to emit Atom 1.0

//Begin commenting here if you are emitting specific syndication standard

if (format == “rss”)

{

return new Rss20FeedFormatter(feed);

}

else if (format == “atom”)

{

return new Atom10FeedFormatter(feed);

}

else

{

return null;

}

//End of comments for specific syndication standard

}

#endregion

}

}

  1. Create a web site as the host for the TemperatureServiceLibrary. Remove the default IService.cs and Service.cs files and add project reference to the TemperatureServiceLibrary project.
  2. Rename the ‘Service.svc’ to ‘TemperatureService.svc’ and change the ServiceHost directive to look like this.

<%@ ServiceHost Service=”TemperatureServiceLibrary.TemperatureService”

Factory=”System.ServiceModel.Activation.WebServiceHostFactory” %>

  1. Change the binding in the Web.config file to ‘webHttpBinding’.
  2. Browse the SVC file. You’ll get an error message, which is expected. Try with the following URL (the port number may be different in your environment).

http://localhost:2263/WebHost/TemperatureService.svc/getforecast/atom

You should see something like this:

Right click on the page and select ‘View Source’. You should see the service result in Atom 1.0 format, like this:

<feed xmlns=”http://www.w3.org/2005/Atom”>

<title type=”text”>Eden Prairie Weather Forecast</title>

<subtitle type=”text”>This is the weather forecast for Eden Prairie</subtitle>

<id>uuid:0a92f15e-1aa7-455d-84ab-261dcd0eac74;id=1</id>

<updated>2010-06-20T18:26:29Z</updated>

<category term=”Weather Forecasts”/>

<author>

<email>weather@appdev.com</email>

</author>

<entry>

<id>Today</id>

<title type=”text”>Day 1 Forecast</title>

<updated>2010-06-20T23:56:29+05:30</updated>

<link rel=”alternate” href=”http://www.mysite.com/”/>

<content type=”text”>Cold, windy, snowy. Low of 20. High of 32.</content>

</entry>

<entry>

<id>Tomorrow</id>

<title type=”text”>Day 2 Forecast</title>

<updated>2010-06-20T23:56:29+05:30</updated>

<link rel=”alternate” href=”http://www.mysite.com/”/>

<content type=”text”>Colder, windier, snowier. Low of 15. High of 20.</content>

</entry>

<entry>

<id>Day After</id>

<title type=”text”>Day 3 Forecast</title>

<updated>2010-06-20T23:56:29+05:30</updated>

<link rel=”alternate” href=”http://www.envirnment.com/”/>

<content type=”text”>blah. blah. blah. Low of 20. High of 31.</content>

</entry>

</feed>

  1. Try the following URL to get the same output, but in RSS 2.0 format.

http://localhost:2263/WebHost/TemperatureService.svc/getforecast/atom

By

Team CVK

Microsoft Competency

www.cvktech.com


RESTful Services in WCF

Posted by admin on Friday, 11 February, 2011

RESTful Services

Representational State Transfer makes WCF services more accessible as it enables the service to emit results in plain XML or as JSON (JavaScript Object Notation).

  1. Create a new WCF Service Library and name it as ‘TemperatureServiceLibrary’.
  2. Rename the default service interface and service implementation files as ‘ITemperatureService.cs’ and ‘TemperatureService.cs’.
  3. Open ‘ITemperatureService.cs’ and modify the code to look like the one below.

using System;

using System.Collections.Generic;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

namespace TemperatureServiceLibrary

{

[ServiceContract]

public interface ITemperatureService

{

[OperationContract]

[WebGet(UriTemplate = "CurrentTemp/{city}",

BodyStyle = WebMessageBodyStyle.Bare)]

int GetCurrentTemp(String city);

[OperationContract]

[WebGet(UriTemplate = "Forecast/{city}",

BodyStyle = WebMessageBodyStyle.WrappedResponse,

ResponseFormat = WebMessageFormat.Json)]

Forecast GetForecast(string city);

[OperationContract]

[WebGet(UriTemplate = "Forecasts",

BodyStyle = WebMessageBodyStyle.WrappedResponse)]

List<Forecast> GetForecasts();

}

[DataContract(Name="Forecast", Namespace="")]

public class Forecast

{

[DataMember(Name="City")]

public string City { get; set; }

[DataMember(Name = "Day1LowTemp")]

public double Day1LowTemp { get; set; }

[DataMember(Name = "Day1HighTemp")]

public int Day1HighTemp { get; set; }

[DataMember(Name = "Day1Details")]

public string Day1Details { get; set; }

[DataMember(Name = "Day2LowTemp")]

public int Day2LowTemp { get; set; }

[DataMember(Name = "Day2HighTemp")]

public int Day2HighTemp { get; set; }

[DataMember(Name = "Day2Details")]

public string Day2Details { get; set; }

}

}

  1. Open ‘TemperatureService.cs’ and type-in the following code.

using System;

using System.Collections.Generic;

namespace TemperatureServiceLibrary

{

public class TemperatureService : ITemperatureService

{

#region ITemperatureService Members

public int GetCurrentTemp(string city)

{

var randomNumber = new Random();

int currentTemp = 0;

switch (city)

{

case “Eden Prairie”:

currentTemp = randomNumber.Next(20, 40);

break;

case “Redmond”:

currentTemp = randomNumber.Next(41, 60);

break;

default:

currentTemp = randomNumber.Next(61, 80);

break;

}

return currentTemp;

}

public Forecast GetForecast(string city)

{

var forecast = new Forecast();

var randomNumber = new Random();

forecast.City = city;

switch (city)

{

case “Eden Prairie”:

forecast.Day1LowTemp = randomNumber.Next(20, 30);

forecast.Day1HighTemp = randomNumber.Next(30, 40);

forecast.Day1Details = “Cold, windy, snowy”;

forecast.Day2LowTemp = randomNumber.Next(10, 20);

forecast.Day2HighTemp = randomNumber.Next(20, 30);

forecast.Day2Details = “Colder, windier, snowier”;

break;

case “Redmond”:

forecast.Day1LowTemp = randomNumber.Next(40, 50);

forecast.Day1HighTemp = randomNumber.Next(50, 60);

forecast.Day1Details = “Rain turning to showers”;

forecast.Day2LowTemp = randomNumber.Next(30, 40);

forecast.Day2HighTemp = randomNumber.Next(40, 50);

forecast.Day2Details = “Showers turning to rain”;

break;

default:

forecast.Day1LowTemp = randomNumber.Next(60, 70);

forecast.Day1HighTemp = randomNumber.Next(70, 80);

forecast.Day1Details = “Sunny and warm”;

forecast.Day2LowTemp = randomNumber.Next(60, 70);

forecast.Day2HighTemp = randomNumber.Next(70, 80);

forecast.Day2Details = “Sunny and warm”;

break;

}

return forecast;

}

public List<Forecast> GetForecasts()

{

var forecasts = new List<Forecast>();

var randomNumber = new Random();

var forecast = new Forecast();

forecast.City = “Eden Prairie”;

forecast.Day1LowTemp = randomNumber.Next(20, 30);

forecast.Day1HighTemp = randomNumber.Next(30, 40);

forecast.Day1Details = “Cold, windy, snowy”;

forecast.Day2LowTemp = randomNumber.Next(10, 20);

forecast.Day2HighTemp = randomNumber.Next(20, 30);

forecast.Day2Details = “Colder, windier, snowier”;

forecasts.Add(forecast);

forecast = new Forecast();

forecast.City = “Redmond”;

forecast.Day1LowTemp = randomNumber.Next(40, 50);

forecast.Day1HighTemp = randomNumber.Next(50, 60);

forecast.Day1Details = “Rain turning to showers”;

forecast.Day2LowTemp = randomNumber.Next(30, 40);

forecast.Day2HighTemp = randomNumber.Next(40, 50);

forecast.Day2Details = “Showers turning to rain”;

forecasts.Add(forecast);

forecast = new Forecast();

forecast.City = “Other”;

forecast.Day1LowTemp = randomNumber.Next(60, 70);

forecast.Day1HighTemp = randomNumber.Next(70, 80);

forecast.Day1Details = “Sunny and warm”;

forecast.Day2LowTemp = randomNumber.Next(60, 70);

forecast.Day2HighTemp = randomNumber.Next(70, 80);

forecast.Day2Details = “Sunny and warm”;

forecasts.Add(forecast);

return forecasts;

}

#endregion

}

}

  1. Create a Web Site to host the service and name it as ‘WebHost’. Remove the ‘IService.cs’ and ‘Service.cs’ that are created by default.
  2. Add project reference to the service library project.
  3. Rename the ‘Service.svc’ to ‘TemperatureService.svc’ and change the ‘ServiceHost’ directive to match the following.

<%@ ServiceHost Service=”TemperatureServiceLibrary.TemperatureService”

Factory=”System.ServiceModel.Activation.WebServiceHostFactory” %>

  1. In the Web.Config file, change the binding to ‘webHttpBinding’.
  2. Try to browse the SVC file. You’ll get an error, which is expected.
  3. Now change the url to the following (the port number may be different in your case):

http://localhost:2263/WebHost/TemperatureService.svc/currenttemp/Redmond

You should see the below output (of course with a random number in the result).

<int xmlns=”http://schemas.microsoft.com/2003/10/Serialization/“>57</int>

  1. Try calling other methods also in similar fashion.
  2. Also, you can try changing the output format to JSON (shown in the code above for GetForecast method).

By

Team CVK

Microsoft Competency

www.cvktech.com


Instancing Modes in WCF

Posted by admin on Friday, 11 February, 2011

Instancing Modes

By now you are well aware that the service is instantiated by ServiceHost and is kept alive until the host is alive. However, you can change this behaviour. You can configure the service in such a way that a new service instance is used for every call or you can make one service instance used by all users and all sessions.

Per-call

  1. Create a new WCF Service Library and name it as ‘GreetingServiceLibrary’.
  2. Rename the default service interface and service implementation files as ‘IGreetingService.cs’ and ‘GreetingService.cs’.
  3. Open ‘IGreetingService.cs’ and modify the code to look like the one below.

using System.ServiceModel;

namespace GreetingServiceLibrary

{

[ServiceContract]

public interface IGreetingService

{

[OperationContract]

string GetGreeting();

[OperationContract]

void SetName(string name);

}

}

  1. Open ‘GreetingService.cs’ and type-in the following code.

using System.ServiceModel;

namespace GreetingServiceLibrary

{

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]

public class GreetingService : IGreetingService

{

string givenName;

#region IGreetingService Members

public string GetGreeting()

{

return “Hi ” + givenName + “, how are you??”;

}

public void SetName(string name)

{

givenName = name;

}

#endregion

}

}

  1. Create a console application to host this service like the way you created in previous examples. Name the project as ‘GreetingConsoleHost’.
  2. Put the following code into ‘Program.cs’.

using System;

using System.ServiceModel;

using GreetingServiceLibrary;

namespace GreetingconsoleHost

{

class Program

{

static void Main(string[] args)

{

using (ServiceHost host = new ServiceHost(typeof(GreetingService)))

{

host.AddServiceEndpoint(“GreetingServiceLibrary.IGreetingService”, new WSHttpBinding(),

“http://localhost:8181/GreetingService”);

host.Open();

Console.WriteLine(“Service started. Press any key to stop.”);

Console.ReadKey();

host.Close();

}

}

}

}

  1. Create a Windows Forms application to act as client. Name the project as ‘GreetingWinApp’.
  2. Modify the form’s interface like this.
  1. Name the text box as ‘NameTextBox’; buttons as ‘SetButton’ and ‘InvokeButton’.
  2. Add project reference to the ‘GreetingServiceLibrary’.
  3. Modify form’s code to the following.

using System;

using System.Windows.Forms;

using GreetingServiceLibrary;

using System.ServiceModel;

namespace GreetingWinApp

{

public partial class Form1 : Form

{

IGreetingService httpChannel;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

httpChannel = ChannelFactory<IGreetingService>.CreateChannel(new WSHttpBinding(),

new EndpointAddress(“http://localhost:8181/GreetingService”));

}

private void InvokeButton_Click(object sender, EventArgs e)

{

ResultLabel.Text = httpChannel.GetGreeting();

}

private void SetButton_Click(object sender, EventArgs e)

{

httpChannel.SetName(NameTextBox.Text);

}

}

}

  1. Run the console host application first and then the Windows forms client.
  2. Input some name and click on ‘Set’. This should store the given name in service’s member variable.
  3. Click on ‘Invoke’. This should return the greeting message with the name stored in the member variable.
  4. However, you see the message without given name because the ‘Invoke’ uses a different instance of the service.

Single

  1. Change the instancing mode to ‘Single’ in the code sample above.
  2. Recompile the service.
  3. Update service reference in client and recompile the client.
  4. Run two instances of the client application from file system.
  5. Type-in name in one instance and click on ‘Set’.
  6. Go to the second instance of the application and click on ‘Invoke’.
  7. Observer that the greeting message is returned with the name given in first instance. This is because both the client instances are using the same service instance.

By

Team CVK

Microsoft Competency

www.cvktech.com


Message Patterns in WCF

Posted by admin on Friday, 11 February, 2011

Message Patterns

By default, the client program makes a synchronous call to the WCF service. This gives a bad user experience when the WCF operation takes long to complete. If you are not interested in the operation result, you could make one-way call to the service operation. If you need the results of the operation but would like to do other things while operation is in progress, you could use duplex message pattern.

One-way pattern

  1. Create a new WCF Service Library and name it as ‘ProductServiceLibrary’.
  2. Rename the default service interface and service implementation files as ‘IProductsService.cs’ and ‘ProductsService.cs’.
  3. Open ‘IProductsService.cs’ and modify the code to look like the one below.

Duplex pattern

  1. Create a new WCF Service Library and name it as ‘ProductServiceLibrary’.
  2. Rename the default service interface and service implementation files as ‘IProductsService.cs’ and ‘ProductsService.cs’.
  3. Open ‘IProductsService.cs’ and modify the code to look like the one below.

using System.Collections.Generic;

using System.Runtime.Serialization;

using System.ServiceModel;

namespace ProductsServiceLibrary

{

[ServiceContract(CallbackContract=typeof(IProductsServiceCallback))]

public interface IProductsService

{

[OperationContract]

[FaultContract(typeof(ConnectionFault))]

[FaultContract(typeof(DataReadFault))]

List<Product> GetProducts();

[OperationContract(IsOneWay = true)]

void GetProductInventory(int productId);

[OperationContract(IsOneWay=true)]

void UpdateInventory();

}

public interface IProductsServiceCallback

{

[OperationContract(IsOneWay = true)]

void GetProductInventoryCallback(int inventory);

}

[DataContract]

public class Product

{

[DataMember]

public int ProductId;

[DataMember]

public string ProductName;

[DataMember]

public string Category;

}

[DataContract]

public class ConnectionFault

{

[DataMember]

public string operation;

[DataMember]

public string message;

}

[DataContract]

public class DataReadFault

{

[DataMember]

public string operation;

[DataMember]

public string message;

}

}

  1. Open ‘ProductsLibrary.cs’ and modify the code to look like this.

using System;

using System.Collections.Generic;

using System.ServiceModel;

using System.Data.SqlClient;

using System.Threading;

namespace ProductsServiceLibrary

{

public class ProductsService : IProductsService

{

#region IProductsService Members

public void UpdateInventory()

{

//Thread.Sleep(new TimeSpan(0, 0, 10));

throw new FaultException(“Some exception from service”);

}

public List<Product> GetProducts()

{

List<Product> products = new List<Product>();

using (SqlConnection conn = new SqlConnection(“server=(local); integrated security=true; initial catalog=Northwind”))

{

try

{

conn.Open();

}

catch (Exception ex)

{

ConnectionFault cf = new ConnectionFault();

cf.operation = “ProductsServiceLibrary.ProductsService.GetProducts”;

cf.message = ex.Message;

//throw new FaultException(new FaultReason(“Problem connecting to the databse. Contact your administrator”),

//    new FaultCode(“ConnectFailure”));

throw new FaultException<ConnectionFault>(cf);

}

using (SqlCommand cmd = new SqlCommand(@”Select p.ProductId, p.ProductName, c.CategoryName

from Products p

inner join Categories c on c.CategoryId = p.CategoryId

Order by p.ProductName”, conn))

{

try

{

SqlDataReader reader = cmd.ExecuteReader();

while (reader.Read())

{

Product prod = new Product();

prod.ProductId = reader.GetInt32(0);

prod.ProductName = reader.GetString(1);

prod.Category = reader.GetString(2);

products.Add(prod);

}

}

catch (Exception ex)

{

//List<FaultReasonText> reasons = new List<FaultReasonText>();

//reasons.Add(new FaultReasonText(“Problem while retrieving data.”, new CultureInfo(“en-US”)));

//reasons.Add(new FaultReasonText(“Error message in Spanish”, new CultureInfo(“es-ES”)));

//throw new FaultException(new FaultReason(reasons),

//    new FaultCode(“DataFailure”));

DataReadFault drf = new DataReadFault();

drf.operation = “ProductsServiceLibrary.ProductsService.GetProducts”;

drf.message = ex.Message;

throw new FaultException<DataReadFault>(drf);

}

}

}

return products;

}

public void GetProductInventory(int productId)

{

int retVal = 0;

using (SqlConnection conn = new SqlConnection(“server=(local); integrated security=true; initial catalog=Northwind”))

{

conn.Open();

using (SqlCommand cmd = new SqlCommand(@”Select p.UnitsInStock

from Products p

where p.ProductId = @ProductId”, conn))

{

cmd.Parameters.Add(new SqlParameter(“@ProductId”, productId));

retVal = (int)cmd.ExecuteScalar();

}

}

IProductsServiceCallback callback = OperationContext.Current

.GetCallbackChannel<IProductsServiceCallback>();

Thread.Sleep(new TimeSpan(0, 0, 10));

callback.GetProductInventoryCallback(retVal);

}

#endregion

}

}

  1. Recompile the service project.
  2. Add a new WCF Service Web Host as ‘WebHost’.
  3. Remove the ‘IService.cs’ and ‘Service.cs’, which are created by default.
  4. Add project reference to the service library project.
  5. Rename the ‘Service.svc’ file as ‘ProductsService.svc’. Double click on the file to open it and change the ServiceHost directive to look like this.

<%@ ServiceHost Service=”ProductsServiceLibrary.ProductsService” %>

  1. Open the Web.config file, find the endpoint declaration. Change ‘wsHttpBinding’ to ‘wsDualHttpBinding’.
  2. Browse the SVC file once to start the ASP.NET Development Server.
  3. Add a new Windows Forms application to act as client for the WCF service. Name it as ‘WinClient’.
  4. Add service reference to the ‘ProductsService’. The ASP.NET development server should be running for this, otherwise the service can’t be found.
  5. Add a new class file to the project. Call it as ‘ServiceCallback.cs’. Code for this file is here.

using System.Windows.Forms;

using WinClient.ProductsService;

namespace WinClient

{

class ServiceCallback : IProductsServiceCallback

{

#region IProductsServiceCallback Members

public void GetProductInventoryCallback(int inventory)

{

MessageBox.Show(“Units remaining in stock: ” + inventory.ToString());

}

#endregion

}

}

  1. Open ‘Data Sources’ window to find ‘Product’ data source. If this window is not available, go to Data menu > Show Data Sources option.
  2. Drag and drop the ‘Product’ data source on to the form. This will automatically create a grid view on the form and the binding automatically happens.
  3. Add controls to the form to look like this.
  1. Name the buttons as ‘GetDataButton’, ‘UpdateInventoryButton’, ‘GetStockButton’ and ‘GetSquareButton’. Name the text box as ‘NumberTextBox’.
  2. ‘Form1.cs’ should look like this.

using System;

using System.Windows.Forms;

using WinClient.ProductsService;

using System.ServiceModel;

namespace WinClient

{

public partial class Form1 : Form

{

ProductsServiceClient proxy;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

ServiceCallback callback = new ServiceCallback();

proxy = new ProductsServiceClient(new InstanceContext(callback));

}

private void GetDataButton_Click(object sender, EventArgs e)

{

try

{

Product[] products = proxy.GetProducts();

productBindingSource.DataSource = products;

proxy.GetProducts();

}

catch (FaultException<ConnectionFault> cf)

{

MessageBox.Show(“Error\n” + cf.Detail.message + “\noccured in ” + cf.Detail.operation, “Connection error”);

}

catch (FaultException<DataReadFault> drf)

{

MessageBox.Show(“Error\n” + drf.Detail.message + “\noccured in ” + drf.Detail.operation, “Data read error”);

}

catch (FaultException fe)

{

switch (fe.Code.Name)

{

case “ConnectFailure”:

MessageBox.Show(fe.Message, “Connection issue”);

break;

case “DataFailure”:

MessageBox.Show(fe.Message, “Data retrieval issue”);

break;

default:

MessageBox.Show(fe.Message, “Unknown issue”);

break;

}

MessageBox.Show(“Unrecognized error”);

}

}

private void GetSquareButton_Click(object sender, EventArgs e)

{

int input = int.Parse(NumberTextBox.Text);

ResultLabel.Text = (input * input).ToString();

}

private void UpdateInventoryButton_Click(object sender, EventArgs e)

{

proxy.UpdateInventory();

}

private void GetStockButton_Click(object sender, EventArgs e)

{

Product selection = (Product)productBindingSource.Current;

proxy.GetProductInventory(selection.ProductId);

}

}

}

By

Team CVK

Microsoft Competency

www.cvktech.com


Using Fault Exception in WCF

Posted by admin on Friday, 11 February, 2011

Since WCF can be consumed by non .NET based clients, the service should not throw .NET specific exceptions. Instead, it should make use of SOAP Fault. The equivalent for SOAP Fault is ‘FaultException’. A FaultException is built with a FaultCode and FaultReason. While FaultCode enables client applications to distinguish between different exceptions; FaultReason allows programmer to pass on friendly messages. This object also allows localization of messages using FaultReasonText object.

using Fault Exception

  1. Create a new WCF Service Library and name it as ‘ProductServiceLibrary’.
  2. Rename the default service interface and service implementation files as ‘IProductsService.cs’ and ‘ProductsService.cs’.
  3. Open ‘IProductsService.cs’ and modify the code to look like the one below.

using System.Collections.Generic;

using System.Runtime.Serialization;

using System.ServiceModel;

namespace ProductsServiceLibrary

{

[ServiceContract]

public interface IProductsService

{

[OperationContract]

List<Product> GetProducts();

}

[DataContract]

public class Product

{

[DataMember]

public int ProductId;

[DataMember]

public string ProductName;

[DataMember]

public string Category;

}

}

  1. Open ‘ProductsService.cs’ and modify code to look like the following.

using System;

using System.Collections.Generic;

using System.ServiceModel;

using System.Data.SqlClient;

namespace ProductsServiceLibrary

{

public class ProductsService : IProductsService

{

#region IProductsService Members

public List<Product> GetProducts()

{

List<Product> products = new List<Product>();

using (SqlConnection conn = new SqlConnection(“server=(local); integrated security=true; initial catalog=Northwind”))

{

try

{

conn.Open();

}

catch (Exception ex)

{

throw new FaultException(“Unable to establish connection with database. “);

}

using (SqlCommand cmd = new SqlCommand(@”Select p.ProductId, p.ProductName, c.CategoryName

from Products p

inner join Categories c on c.CategoryId = p.CategoryId

Order by p.ProductName”, conn))

{

try

{

SqlDataReader reader = cmd.ExecuteReader();

while (reader.Read())

{

Product prod = new Product();

prod.ProductId = reader.GetInt32(0);

prod.ProductName = reader.GetString(11);

prod.Category = reader.GetString(2);

products.Add(prod);

}

}

catch (Exception ex)

{

List<FaultReasonText> reasons = new List<FaultReasonText>();

reasons.Add(new FaultReasonText(“Problem while retrieving data.”, new CultureInfo(“en-US”)));

reasons.Add(new FaultReasonText(“Error message in Spanish”, new CultureInfo(“es-ES”)));

throw new FaultException(new FaultReason(reasons),

new FaultCode(“DataFailure”));

}

}

}

return products;

}

#endregion

}

}

  1. Here is the code for ‘GetData’ button’s click event.

private void GetDataButton_Click(object sender, EventArgs e)

{

try

{

Product[] products = proxy.GetProducts();

productBindingSource.DataSource = products;

}

catch (FaultException fe)

{

switch (fe.Code.Name)

{

case “ConnectFailure”:

MessageBox.Show(fe.Message, “Connection issue”);

break;

case “DataFailure”:

MessageBox.Show(fe.Message, “Data retrieval issue”);

break;

default:

MessageBox.Show(fe.Message, “Unknown issue”);

break;

}

}

}

By

Team CVK

Microsoft Competency

www.cvktech.com


Creating and Working With Custom Bindings in WCF

Posted by admin on Friday, 11 February, 2011

Creating and working with Custom Bindings

WCF comes with bindings that satisfy most of our application needs. However, there may be a time where you want to choose your own settings for a binding. That’s when you create a custom binding and define the channel stack for it. Here is to do that.

  1. Take the solution you created in the previous code sample or follow the same steps to create a new solution.
  2. Modify the service host code by commenting/removing the existing endpoints and by adding a new custom binding. The finished code should look like this. You may need to add System.ServiceModel.Channels and System.Text namespaces in order to work with the below code.

static void Main(string[] args)

{

ServiceHost host = new ServiceHost(typeof(GreetingService));

BindingElementCollection binElement = new BindingElementCollection();

binElement.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));

binElement.Add(new HttpTransportBindingElement());

CustomBinding myBinding = new CustomBinding(binElement);

host.AddServiceEndpoint(“GreetingServiceLibrary.IGreetingService”, myBinding,

“http://localhost:9999/GreetingService”);

host.Open();

foreach (ServiceEndpoint endp in host.Description.Endpoints)

{

Console.WriteLine(“{0} – {1}”, endp.Address, endp.Binding.Name);

Console.WriteLine(“{0}”, endp.Binding.MessageVersion);

Console.WriteLine();

}

Console.WriteLine(“The service has started. Press any key to stop…”);

Console.ReadKey();

host.Close();

}

  1. Now open the client code and remove/comment the existing channel creation code. The finished code should look like this.

private void Form1_Load(object sender, EventArgs e)

{

BindingElementCollection binElement = new BindingElementCollection();

binElement.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));

binElement.Add(new HttpTransportBindingElement());

CustomBinding myBinding = new CustomBinding(binElement);

customChannel = ChannelFactory<IGreetingService>.CreateChannel(myBinding,

new EndpointAddress(“http://localhost:9999/GreetingService”));

}

private void InvokeButton_Click(object sender, EventArgs e)

{

MessageBox.Show(customChannel.GetGreeting(NameTextBox.Text));

}

  1. Run the program and see that you are getting response from the service.

By

Team CVK (Microsoft Competency)

www.cvktech.com