Syndication in WCF –

February 11, 2011 Posted by admin

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

February 11, 2011 Posted by admin

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

February 11, 2011 Posted by admin

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

February 11, 2011 Posted by admin

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 Custom Fault Exception in WCF

February 11, 2011 Posted by admin

using Custom 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]

[FaultContract(typeof(ConnectionFault))]

[FaultContract(typeof(DataReadFault))]

List<Product> GetProducts();

}

[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;

[DataMember]

public string Reason;

}

[DataContract]

public class DataReadFault

{

[DataMember]

public string operation;

[DataMember]

public string message;

[DataMember]

public string Reason;

}

}

  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)

{

ConnectionFault cf = new ConnectionFault();

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

cf.message = ex.Message;

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(11);

prod.Category = reader.GetString(2);

products.Add(prod);

}

}

catch (Exception ex)

{

DataReadFault drf = new DataReadFault();

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

drf.message = ex.Message;

drf.Reason = “Data read failure”;

throw new FaultException<DataReadFault>(drf);

}

}

}

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<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)

{

MessageBox.Show(“Unrecognized error”);

}

}

By

Team CVK

Microsoft Competency

www.cvktech.com

Using Fault Exception in WCF

February 11, 2011 Posted by admin

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

February 11, 2011 Posted by admin

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

Creating , Cosuming , Hosting and Configuring a WCF Service

February 11, 2011 Posted by admin

Windows Communication Foundation (WCF)

Creating and consuming ‘GreetingService’

1.       Open Visual Studio 2008

2.       Select File – New – Project

  1. In the new project dialog, select WCF Service Library. Type-in the project name as ‘GreetingServiceLibrary’ and solution name as ‘GreetingService’ and click OK.
  1. After the project is created and opened, you should be able to see IService.cs and Service.cs files as part of the project. Rename these files to IGreetingService.cs and GreetingService.cs respectively.
  2. Remove existing code in IGreetingService.cs and type the following.

using System.ServiceModel;

namespace GreetingServiceLibrary

{

[ServiceContract]

public interface IGreetingService

{

[OperationContract]

string GetGreeting(string yourName);

}

}

  1. Remove existing code in GreetingService.cs and type the following.

namespace GreetingServiceLibrary

{

public class GreetingService : IGreetingService

{

#region IGreetingService Members

public string GetGreeting(string yourName)

{

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

}

#endregion

}

}

  1. Now you can run the project to see if the service is working fine. When you run at this point of time, the service is hosted in Visual Studio’s default ‘Service Host’ and invoked through ‘WCF Test Client’.
  1. Now, add a Web Host to the solution by going to File > Add… > New Web Site…
  2. Name the Web Site as ‘GreetingWebHost’.
  3. You should see ‘IService.cs’ and ‘Service.cs’ as part of the newly created project. Remove these files as we already have the service defined in the service library.
  4. Add a reference to the project ‘GreetingServiceLibrary’, which we just created.
  5. Find the file ‘Service.svc’ file in the project and rename it to ‘GreetingService.svc’.
  6. Double click to open the ‘GreetingService.svc’ file. Change the only line available there to look like this:

<%@ ServiceHost Service=”GreetingServiceLibrary.GreetingService” %>

  1. Open ‘Web.config’ file and scroll down to the ‘<system.serviceModel>’ element.
  2. Under this, find ‘service’ element and change ‘name’ attribute value to ‘GreetingServiceLibrary.GreetingService’.
  3. Find ‘endpoint’ element and change ‘contract’ attribute value to ‘GreetingServiceLibrary.IGreetingService’.
  4. In the Web.Config file, find the ‘compilation’ element and change ‘debug’ attribute value to ‘true’.
  5. Now it’s time to create client application. Add a Windows Forms Application to the solution and name it as ‘GreetingWinApp’.
  6. Add a TextBox and a Button control to the form and make them look like:
  1. Name the TextBox as ‘NameTextBox’ and the Button as ‘InvokeButton’.
  2. Add service reference to the current project. Select ‘GreetingWebHost’ while adding Service Reference.
  1. Create event handlers and modify source code so that it looks like the following.

using System;

using System.Windows.Forms;

using GreetingWinApp.GreetingService;

namespace GreetingWinApp

{

public partial class Form1 : Form

{

GreetingServiceClient proxy;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

proxy = new GreetingServiceClient();

}

private void InvokeButton_Click(object sender, EventArgs e)

{

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

}

}

}

  1. Right click on the solution and select ‘Properties…’. In the properties window, select ‘Multiple startup projects’ and make changes like this.
  1. Now the solution can be executed to see if everything is working fine.

Self-hosting a WCF Service

While self-hosting WCF Service refers to creating Service Host in Console application/Windows Forms application/Windows Service, the following code example shows how to create a console host.

  1. Follow the steps 1 to 8 from the previous code sample to create GreetingServiceLibrary.
  2. Add a console application to the project. Name the new project as ‘GreetingConsoleHost’.
  3. Add a reference to the ‘GreetingServiceLibrary’ project.
  4. Open ‘Program.cs’ and modify code to look like this.

using System;

using GreetingServiceLibrary;

using System.ServiceModel;

using System.ServiceModel.Description;

namespace GreetingConsoleHost

{

class Program

{

static void Main(string[] args)

{

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

host.AddServiceEndpoint(“GreetingServiceLibrary.IGreetingService”,

new NetTcpBinding(),

“net.tcp://localhost:9000/GreetingService”);

host.Open();

foreach (ServiceEndpoint endp in host.Description.Endpoints)

{

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

Console.WriteLine();

}

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

Console.ReadKey();

host.Close();

}

}

}

  1. Compile the console application. Don’t run it yet.
  2. Now, follow steps 18 to 20 to add a Windows Forms application to the solution.
  3. Create event handlers and make the code look like:

using System;

using System.Text;

using System.Windows.Forms;

using System.ServiceModel;

using GreetingServiceLibrary;

using System.ServiceModel.Channels;

namespace WindowsClient

{

public partial class Form1 : Form

{

IGreetingService tcpChannel;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

tcpChannel = ChannelFactory<IGreetingService>

.CreateChannel(new NetTcpBinding(),

new EndpointAddress(“net.tcp://localhost:9000/GreetingService”));

}

private void InvokeButton_Click(object sender, EventArgs e)

{

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

}

}

}

  1. Right click on solution and select ‘Properties…’ to changed the startup object settings.
  1. Run the solution to see if everything is working.

Configuring multiple endpoints

This is one of the reasons why WCF is superior to Web Services. A service host can house multiple services and each service can be configured to be available in different configurations (protocols and ports). The following example shows how.

  1. Take the solution you created in the previous code sample or follow the same steps to create a new solution.
  2. Open the ‘Program.cs’ of ‘GreetingConsoleHost’. Modify the code to look like this.

using System;

using GreetingServiceLibrary;

using System.ServiceModel;

using System.ServiceModel.Description;

namespace GreetingConsoleHost

{

class Program

{

static void Main(string[] args)

{

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

host.AddServiceEndpoint(“GreetingServiceLibrary.IGreetingService”,

new NetTcpBinding(),

“net.tcp://localhost:9000/GreetingService”);

host.AddServiceEndpoint(“GreetingServiceLibrary.IGreetingService”,

new BasicHttpBinding(),

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

host.Open();

foreach (ServiceEndpoint endp in host.Description.Endpoints)

{

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

Console.WriteLine();

}

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

Console.ReadKey();

host.Close();

}

}

}

  1. Open the form in the Windows Forms client application.
  2. Change existing button’s text as ‘TCP Invoke’.
  3. Add one more button to the form and call it as ‘HTTP Invoke’. Add ‘Click’ event handler to this button.
  4. Make sure the form’s code looks like this.

using System;

using System.Text;

using System.Windows.Forms;

using System.ServiceModel;

using GreetingServiceLibrary;

using System.ServiceModel.Channels;

namespace WindowsClient

{

public partial class Form1 : Form

{

IGreetingService tcpChannel;

IGreetingService httpChannel;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

tcpChannel = ChannelFactory<IGreetingService>

.CreateChannel(new NetTcpBinding(),

new EndpointAddress(“net.tcp://localhost:9000/GreetingService”));

httpChannel = ChannelFactory<IGreetingService>

.CreateChannel(new BasicHttpBinding(),

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

}

private void InvokeButton_Click(object sender, EventArgs e)

{

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

}

private void HTTPInvokeButton_Click(object sender, EventArgs e)

{

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

}

}

}

  1. Run the program. When you enter text and click on ‘TCP Invoke’ button, the service is contacted using NetTcpBinding (TCP protocol and port 9000). And, if you click on ‘HTTP Invoke’ the service is contacted using BasicHttpBinding (HTTP protocol and port 8000).

Working with configuration files

While you can create endpoints through code, it is a recommended practice to have endpoints defined in a configuration file. This will enable you to change configuration or even add/remove endpoints at any time, without touching the code. To make things easy, Visual Studio comes with ‘WCF Service Configuration Editor’ utility to create/modify configuration files.

In the following example, let’s move the endpoints on the ‘GreetingConsoleHost’ from code to configuration file.

  1. Take the solution you created in the previous code sample or follow the same steps to create a new solution.
  2. Go to ‘Tools’ menu, choose ‘WCF Service Configuration Editor’.
  3. In the newly opened window, go to ‘File’ menu and choose ‘New Config’.
  4. The interface changes and presents you with options to create service configuration. Choose ‘Create a New Service…’
  1. ‘New Service Element Wizard’ starts. Click on the ‘Browse…’ button.
  1. Select the service library’s output file (DLL) from appropriate location.
  1. The wizard will show the class that implements service interface. Click ‘Open’
  2. Click ‘Next’ on the wizard. You’ll be asked to choose the Service Contract. This is automatically selected for you, so you can click ‘Next’.
  3. The next step is to choose the protocol (thereby choosing the binding). Choose ‘HTTP’ and click ‘Next’.
  1. Since there are multiple types of HTTP based bindings available, you’ll be asked to choose a specific one. ‘Basic Web Services interoperability’ gives you ‘BasicHttpBindig’. ‘Advanced Web Service ineroperability’ with ‘Simplex communication’ gives you ‘WsHttpBinding’ and with ‘Duplex communication’ it gives you ‘WsDualHttpBinding’. Choose first one for now and click ‘Next’.
  1. In the next step, you’ll be asked for the address. Give ‘http://localhost:8000/GreetingService’ and click ‘Next’.
  2. A summary of chosen settings will be shown. Click ‘Finish’ to end the wizard.
  3. The endpoint is now created but without a name. Use the service editor interface to assign a name.
  1. Create new endpoint for ‘NetTcpBinding’. The finished settings should look like this.
  1. Go to ‘File’ menu and choose ‘Save’ option.
  2. Choose the ‘GreetingConsoleHost’ project location to save the ‘App.Config’ file.
  3. Close the service editor window.
  4. Open the ‘Program.cs’ in the ‘GreetingConsoleHost’ project.
  5. Comment/remove the lines inside ‘Form_Load’ event handler (the lines that create endpoints).
  6. Run the solution. It should run as it did in the previous example. The change here is endpoints are now created from configuration file instead of code.

By

Team CVK (Microsoft Competency)

www.cvktech.com

Using Code in Application Page Of SharePoint 2010

February 4, 2011 Posted by admin

Using Code in Pages

Content pages are ASPX pages, and are therefore intended to contain custom code. However, because end users can distribute such pages, and active code can potentially harm a server’s reliability, there are several security restrictions. As a general rule, inline code is not supported within a custom content page. You are supposed to use code-behind classes to provide code to content pages to overcome this restriction.

A special configuration section, <SafeControls>, defines the controls permitted on content pages. To prevent users from uploading Web Parts containing harmful custom code, the code portion must be explicitly registered in the <SafeControls> section. Otherwise, SharePoint will not execute it. As a general rule you should avoid custom code in content pages. However, internal pages can execute code at any time. If you create a new site definition using modified content pages with custom code, they will execute just fine. If a user later modifies those pages, making them ghosted, the code will no longer execute. To avoid this confusing behavior you should not use custom code in common content pages. However, as with most other extensible parts on ASP.NET, the administrator of a farm can override this behavior by configuring the Virtual Path Provider. This provider is responsible for retrieving the page from wherever it is stored (file system or database) and handing it over for execution. The following definition in web.config enables the execution of server-side code:

<SharePoint>

<SafeMode …>

<PageParserPaths>

<PageParserPath VirtualPath=”/_mpg/*”

CompilationMode=”Always”

AllowServerSideScript=”true”

IncludeSubFolders=”true”/>

</PageParserPaths>

If you plan to create complete applications using code, using application pages is much more

powerful and less confusing.

By

Team CVK , Microsoft Competency

Activating Developer Dashboard in SharePoint 2010

February 4, 2011 Posted by admin

Activating the Developer Dashboard Using stsadm

By default the Developer Dashboard is switched off. To activate it on your machine, you can run a stsadm command:

stsadm –o setproperty –pn developer-dashboard –pv ondemand

The command switch -pv accepts the following settings:

• on: Activate the Developer Dashboard (always appears at the end of a page)

• off: Deactivate

• ondemand: Activate on Demand

The ondemand option is usually the best choice, as it allows you to show or hide the information

using the dashboard icon in the upper-right corner,

Note launching this command takes some time even on a fast machine.

The on option is helpful if the layout of a page is destroyed or you can’t reach the Dashboard icon for

some reason.

Activating the Developer Dashboard Using Power Shell

To activate the Developer Dashboard via Power Shell, use a script such as this:

$level=”Off”

[void][System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)

[void][System.Reflection.Assembly]::LoadWithPartialName

(“Microsoft.SharePoint.Administration”)

$contentSvc=[Microsoft.SharePoint.Administration.SPWebService]::ContentService

$contentSvc.DeveloperDashboardSettings.DisplayLevel=

([Enum]::Parse(

[Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel],

$level))

$contentSvc.DeveloperDashboardSettings.Update()

Write-Host(“Current Level: ” + $contentSvc.DeveloperDashboardSettings.DisplayLevel)

The supported properties for the $level variable are the same as those for stsadm:

• “On”: Activate the Developer Dashboard (always appears at the end of a page)

• “Off”: Deactivate

• “OnDemand”: Activate on Demand

Activating the Developer Dashboard Using Code

You’re probably going to write some clever tools for SharePoint. Using code to activate the dashboard

may help others to investigate what they are doing. A simple piece of code does the trick:

SPWebService svc = SPWebService.ContentService;

svc.DeveloperDashboardSettings.DisplayLevel = SPDeveloperDashboardLevel.OnDemand;

svc.DeveloperDashboardSettings.Update();

Note that the usage of the SPFarm object, which is shown in several blogs regarding earlier versions

of SharePoint 2010, is no longer supported in the final SharePoint product.

Working with the Developer Dashboard

This tool will give you the following:

• A breakdown of the request/response cycle with timings for each operation

• A breakdown of the response times for each database query that the rendering

process triggers

• A breakdown of the load times for each Web Part on the page

By

Team CVK , Microsoft Competency