ramlicious Blogs by Tina & Prabhu

December 2, 2011

Exception handling in WCF Services using SOAP Faults

Filed under: .NET,C#,Programming,WCF — Prabhuram @ 3:07 pm

One way I handle exceptions between WCF services and the service client proxy class is using the SOAP Faults. All you do is:

  1. Introduce <serviceDebug> attribute in the serviceBehavior\behavior element with includeExceptionDetailInFaults=”Boolean”
  2. Introduce a DataContract class that can take the properties that you wanted to pass to the proxy client.
  3. Decorate the OperationContract method with another attribute called FaultContract.
  4. Throw the FaultException from with the OperationContract.
The change in the service’s web.config will be
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"  />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

and the exception carrier will be something like this.

    [DataContract]
    public class MyException
    {
        [DataMember]
        public string ErrorMessage { get; set; }

        public MyException()
        {

        }

        public JsfException(string message)
        {
            this.ErrorMessage = message;
        }
    }

and service’s operation contract is decorated with FaultContract.

    [ServiceContract]
    public partial class MyServices
    {

        [OperationContract]
        [FaultContract(typeof(MyException))]
        public int Exec(int something)
        {
            // Do something
        }
    }

and now you will throw the exception like this.

    [ServiceContract]
    public partial class MyServices
    {

        [OperationContract]
        [FaultContract(typeof(MyException))]
        public int Exec(int something)
        {
            try
            {
                // Do something
            }
            catch (Exception ex)
            {
                MyException errMsg = new MyException(ex.Message) { Source = ex.Source };
                throw new FaultException<MyException>(errMsg, new FaultReason(errMsg.ErrorMessage), new FaultCode("MyCode"));
            }
        }
    }

and you can simply use this from the client like this.

        try
        {
            // Do something
        }
        catch (FaultException<MyException> ex)
        {
        }

November 30, 2011

Problem with the “Specified” property when generating WCF proxy classes

Filed under: .NET,C#,Programming,WCF — Prabhuram @ 6:59 pm

I was creating WCF services today and I encountered a weird problem when generating proxy clients for the services. When creating proxy classes using SvcUtil.exe for my presentation tier, the utility creates a xxxIsSpecified property for all the value type decorated with DataMembers attributes(like int, bool, etc)

[DataContract()]
public class MyClass
{
	[DataMember()]
	public int IntMember { get; set; }
}

So in this case, the property IntMember exposes an another property called IntMemberSpecified in the proxy class. After referring at many pointers and blogs (not from MSDN), I was able to overcome this by simply setting IsRequired = true property to the DataMember() attribute. So the class should look like this after the change.

[DataContract()]
public class MyClass
{
	[DataMember(IsRequired=true)]
	public int IntMember { get; set; }
}

You will note that this problem doesn’t happen when you use the Add Service Reference from Visual Studio.

September 14, 2011

OData and JSON

Filed under: JSON,OData,Visual Studio,WCF,XML — Prabhuram @ 1:18 pm

In my last two article which talks about developing WCF data services, you would have noted that when you browsed the .svc page (http://localhost/ODataSampler.Web/MusicAlbum.svc/) from the browser the XML appears something like this:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<service xml:base="http://localhost/ODataSampler.Web/MusicAlbum.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
  <workspace>
    <atom:title>Default</atom:title>
    <collection href="Albums">
      <atom:title>Albums</atom:title>
    </collection>
  </workspace>
</service>

This is the AtomPub format (yes the same format weblogs are distributed). OData supports AtomPub and JSON. In this article we will quickly see how JSON format. In this case, I will use Netflix source. I’ve created a very simple HTML page to demostrate the power of OData.

HTMLPage.htm (976.00 bytes)

Simply click open the link and open the file in a browser, and check out what happens. All that the file contains is a simple call to pull the JSON data from Netflix. And you can also see that HTML only has very simple JQuery calls to pull the data. And when you view the source, it doesn’t have any movie data on the client side, and so everything happens on the fly.

Here is the URI used in the HTML file

http://odata.netflix.com/Catalog/Titles?$filter=ReleaseYear%20eq%202011&$format=json&$callback=?&$orderby=Name

pulls the movie titles released in 2011, and the requested data format is json. So if you just click open the link you can see the actual json data.

Using OData Services

Filed under: C#,OData,Visual Studio,WCF — Prabhuram @ 7:26 am

After writing WCF Data Services with an example (OData Sample), I realized that I could have showed the service that we just created with an example by calling the Data Service from a console application, so I created a console application and then added a service reference to the .svc source and then simply able to call the data service.

    class Program
    {
        static void Main(string[] args)
        {
            foreach (var p in new MusicAlbumService(new Uri("http://localhost/ODataSampler.Web/MusicAlbum.svc/")).Albums)
                System.Console.WriteLine(p.Name);
            System.Console.ReadKey();
        }
    }

How easy is that!!

WCF Data Services with an example (OData Sample)

Filed under: C#,OData,Visual Studio,WCF — Prabhuram @ 3:42 am

I did this example with VS2008. Have this pre-requisites in place for working with OData services

  • Visual Studio 2008 with SP1 (required for ADO.NET Entity Model)
  • .NET 3.5 with SP1
  • IIS 7.0 (I was using a Win7 station)
  • Run this command from VS command prompt if you don’t have a HTTP handler for .SVC in IIS.
    %WinDir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\servicemodelreg –i
  • Always have this super tool LINQPad.exe. You guys will need this all the time.

This article is for the novice users to jumpstart, experiment and learn about the ADO.NET Data Services (formerly code named Astoria and called WCF Data Services in .NET 4.0). First create a Web application and add two simple classes.

namespace MyServices
{
    [DataServiceKey("Name")] //To avoid Request Error, introduce a Primary Key
    public class MusicAlbum
    {
        public string Name { get; set; }
        public string Artist { get; set; }
        public int Year { get; set; }
        public MusicAlbum(string Name, string Artist, int Year)
        {
            this.Name = Name;
            this.Artist = Artist;
            this.Year = Year;
        }
    }
    public class MusicAlbumService
    {
        List list = new List(){
            new MusicAlbum("Eagles", "Eagles", 1972),
            new MusicAlbum("Queen", "Queen", 1973)};
        public IQueryable Albums
        {
            get
            {
                return list.AsQueryable();
            }
        }
    }
}

And introduce your Data Service Page by adding ADO.NET Data Service from Add New Item. Make the following changes by introducing the MusicAlbumService as the Data Service.

public class WebDataService : DataService< MusicAlbumService >
{
    public static void InitializeService(IDataServiceConfiguration config)
    {
         config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
    }
}

Compile this project and host MusicAlbum.svc. Now we will test this data source in LINQPad, and so we will add a connection to the .svc file.


And note that you can query the database like:

from p in Albums select p

To give a better understanding WCF Data Service is basically an implementation of OData (Open Data Protocol). Also you can make changes to the query like this and execute:

from p in Albums where p.Name == "Eagles" select p

and the reason why I used LINQPad is to show the SQL tab that shows you the SQL equivalent

http://localhost/ODataSampler.Web/MusicAlbum.svc/Albums('Eagles')

As you can see, you can copy the URI and paste it in a browser to see the results over the web.

So you learnt:

  • With in short time you are able to expose a datasource (without a database) to outside world
  • And you are able to achieve this over the web on HTTP as a URI
  • The metadata of the data service is available to the client (that way LINQPad was able to understand about MusicAlbum)
  • Ofcourse it is interoperable
  • A relational data model approach
  • Moreover it allows to apply business logic from the client by including custom filter criterias
  • There are multiple implementation of OData across multiple platforms and for the .NET developers it is part of .NET3.5+

Download the complete VS solution from here: ODataSampler.Web.zip (3.51 mb)

Query against those OData sources that are availableover the internet like eBay, and Netflix.

September 13, 2011

Scoping WCF Services

Filed under: C#,Visual Studio,WCF — Prabhuram @ 5:04 am

Here is another example that will show the scope of the service and the fields to demonstrate the instancing behavior of services and clients. In this example I’ve created projects similar to my earlier WCF example but with few exception. This time I’m not using a business layer and I’m using simple return types instead of data contracts. I’ve used four projects:

  • ContextBehavior.Contract references System.ServiceModel
    • IMathOperation.cs
    • MathOperationClient.cs
  • ContextBehavior.Service references System.ServiceModel and ContextBehavior.Contract
    • MathOperation.cs
  • ContextBehavior.Host references System.ServiceModel, ContextBehavior.Contract and ContextBehavior.Service
    • Program.cs
    • App.config
  • ContextBehavior.Client references System.ServiceModel and ContextBehavior.Contract
    • Program.cs
    • App.config

First it is important to understand that WCF makes development easier.

  • The developer of the service doesn’t have to know about how the service will be used after implementation and so WCF clearly demarcates development and implementation
  • As an end product the service can be hosted in HTTP or TCP and so it brings together the advantages of web service and also remoting (.Net remoting) and hence you have the option on sending binary content over the wires and just not limited to plain text (XML)
  • Moreover WCF is highly secure and robust provides different instantiation capabilities (which we will see in our example)
  • Services can be either hosted in HTTP or as a Windows Services or can be self hosted (like our example)

The purpose of our service is demostrate a simple increment method. We are going to run our application in three different modes:

  • PerCall, each call made to the service is treated as an independent call
  • PerSession, each call from a particular session will be treated as part of an unexpired session (already instantiated session) and so retaining the state of the hosted object
  • Singleton, different calls from different sessions will be routed to one single hosted session and thus sharing the state of the hosted object

The complete project is available for download: ContextBehavior.zip (79.70 kb)

With this project we are going to test the three different instance contexts.  To test these we are going to decorate the service behavior of the service object with different settings to test the different behaviors from the client. Our host is a self-hosting console application that is set as the default project to run. To test the clients we are going to run the client application in debug mode such that both the host and client are debugged at the same time. First we will decorate our service with PerCall InstanceContextMode like this:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MathOperation : IMathOperation
{
}

We will run the client using the proxy client:

static void Main(string[] args)
{
  MathOperationClient client = new MathOperationClient();
  do
  {
    Console.WriteLine("Executed Increment(), value is " + client.Increment().ToString());
    Console.WriteLine("Press Y to continue...");
  }
  while (Console.ReadKey().Key.Equals(ConsoleKey.Y));
}

We can debug this by running multiple clients and making multiple calls to the service by repeatedly pressing N. As you can see since the result will always return 1 because of the PerCall Instance type. By just changing the Mode to PerSession,

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]

each call from the same session will retain the session’s state and you can see the numbers incrementiong, and by changing the Mode to Single,

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]

each call across all the session will retain the value made the earlier call.

Guess this gives you an understanding.

September 12, 2011

A simple implementation of WCF Service with an example

Filed under: C#,Visual Studio,WCF — Prabhuram @ 1:43 pm

I’ve created a sample set of projects for those who wanted to learn WCF basics. Let me assume that you wanted to learn the fundamentals of WCF and so I will assume that this is your first hands on WCF project, so that I can create a project for the dummies.

I created this project in VS2008 and the development is the same in VS2010 and I am using .NET Framework 3.5. Here is a screenshot of the solution explorer and I have created five projects. WCFSample.Host is a command-line application, WCFSample.Client is a winforms application and the remaining projects are class library.

So we will visit the projects in the order they should be created. My first project called the WCFSample.Business contains objects necessary for searching through abbreviations. I’ve used a simple collection (for the purpose just understanding the basics) which can be extended to search through database tables or XML files.

public class Abbreviation
{
  public string Abbr;
  public string Word;
  public Abbreviation(string Abbreviation, string Word)
  {
    this.Abbr = Abbreviation;
    this.Word = Word;
  }
}


and so basically my primary business method that will be used by the service will be FindByAbbreviation():

   public class AbbreviationHelper : Dictionary<string, string>
    {
        private static List<Abbreviation> list = new List<Abbreviation>(){
            new Abbreviation("fbi", "federal bureau of investigations"),
            new Abbreviation("cia", "central intelligence agency"),
            new Abbreviation("nypd", "new york police department")
        };
        public string FindByAbbreviation(string Abbreviation)
        {
            var sel = from item in list
                      where item.Abbr == Abbreviation
                      select item;
            return sel.Single().Word;
        }
    }

And the next project that comes to play is to create the WCFSample.Contract. First create the Interface that defines the contract. For more on how to refer to the MSDN article here.

    [ServiceContract]
    public interface IAbbrExpander
    {
        [OperationContract]
        WordSet Expand(string Abbreviation);
    }

And here is the declaration of WordSet:

    public class WordSet
    {
        public string Abbreviation;
        public string Word;
    }

And next is to create the implementation of IAbbrExpander in the WCFSample.CoreService project

    public class AbbrExpander : IAbbrExpander
    {
        public WordSet Expand(string Abbreviation)
        {
            AbbreviationHelper list = new AbbreviationHelper();
            string str = list.FindByAbbreviation(Abbreviation);
            WordSet word = new WordSet();
            word.Abbreviation = Abbreviation;
            word.Word = str;
            return word;
        }
    }

In our case we are going to create a self-hosting service and so the command-line project’s Main() will be like the one below:

       static void Main(string[] args)
        {
            using (ServiceHost svc = new ServiceHost(typeof(AbbrExpander)))
            {
                svc.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.Read();
            }
        }

The important thing in hosting the service is the configuration and I’ve done this configuration in App.config which can also be done programmatically:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="WCFSample.CoreService.AbbrExpander">
        <endpoint
          address="http://localhost:8080/abbr"
          binding="wsHttpBinding"
          contract="WCFSample.Contract.IAbbrExpander"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

At this time you can run the command-line application to see if it works. Also notice every little attribute and element in the app.config is important and you can learn more about them from MSDN reference library.

Now we will utilize this service from a winform application.  First introduce a app.config and make the necessary changes to give the ABCs of the service:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
        <endpoint
          address="http://localhost:8080/abbr"
          binding="wsHttpBinding"
          contract="WCFSample.Contract.IAbbrExpander" />
    </client>
  </system.serviceModel>
</configuration>

To utilize the service we need to introduce a client proxy, and so we will add the class in WCFSample.Contract:

    public class AbbrExpanderClient : ClientBase<IAbbrExpander>, IAbbrExpander�
    {
        public WordSet Expand(string Abbreviation)
        {
            return Channel.Expand(Abbreviation);
        }
    }

and atlast we will introduce the event handler in our button_click to call the service and it simply goes like this:

     private void button1_Click(object sender, EventArgs e)
     {
         try
         {
             AbbrExpanderClient client = new AbbrExpanderClient();
             MessageBox.Show(client.Expand(textBox1.Text).Word);
         }
         catch(Exception ex){
             MessageBox.Show (ex.Message);
         }
     }

And so if you enter nypd in the text box and click search, a message box should pop-up with the result.

Powered by WordPress