Gigi Labs

Please follow Gigi Labs for the latest articles.
Showing posts with label wcf. Show all posts
Showing posts with label wcf. Show all posts

Saturday, August 23, 2014

C# WCF: Backslash Limitation in WCF Test Client

Welcome! :)

Last year, I wrote an introductory WCF article, "C# WCF: A Minimal Client and Server Using Visual Studio 2012". In this article, we explored how to create a simple WCF service, and how to communicate with it using either the WCF Test Client provided with Visual Studio, or via client code. Visual Studio conveniently takes care of much of the plumbing involved in getting client and server to communicate with each other.

In today's article, we will be creating another simple WCF service to learn about a limitation in the WCF Test Client that bit me just yesterday - an issue you'll no doubt come across when using the WCF Test Client to send a string parameter containing a backslash.

First, let us create a new WCF Service Library project:


Now, by default you will have a service called Service1 that exposes a simple method called GetData(). You can test this directly using the WCF Test Client. Press F5 to launch the WCF Test Client; then double-click on the GetData() method, enter a value for the value parameter, and press the Invoke button to see the result (just as we had done in "C# WCF: A Minimal Client and Server Using Visual Studio 2012":


Next, let's add a new method called Echo() to our IService1 interface, which is our Service Contract. This is what it should look like:

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);

        [OperationContract]
        string Echo(string text);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: Add your service operations here
    }


With this done, let us now add an implementation for our Echo() method in the Service1 class:

        public string Echo(string text)
        {
            return text;

        }

Nothing special there - the server echoes the input back to the client, much like we had done in "C# Network Programming: Echo Client/Server". Now, let's fire up the WCF Test Client again (F5) and test our new method:


With an input of "Brazil nuts", it worked fine. Now let's try a fictional domain username:


This time, instead of getting back the data we sent, we're getting a null! Why is that? Let's put a breakpoint in our Echo method and investigate:


Well, as you can see, the input itself is arriving as null, so there's nothing wrong with our logic. To investigate further, switch to the XML tab in the WCF Test Client, where you can actually see the underlying data that is being sent and received:


And even here, you'll see that a null is being sent. It turns out that the problem is that the WCF Test Client does not escape backslashes, so it will convert the whole input to null if it encounters an escape sequence it doesn't recognise (in our case \d); but it does work normally when you send a recognised escape sequence, such as \n:


So whenever you use the WCF Test Client, always escape slashes you actually intend to send as such:


You don't have to do this if you communicate with your WCF service in code, of course.

Note: while this may or may not be seen as limitation in the WCF Test Client (since it's technically allowing you to enter a raw string), it's pretty evil that it silently converts the input string to null when it fails to parse it correctly.

Thanks for reading, and I hope someone finds this useful! :)

Monday, November 25, 2013

C# WCF: A Minimal Client and Server Using Visual Studio 2012

Hey there! :)

In this article we'll be taking a brief look at how to set up a very simple WCF client and server. We're actually going to let Visual Studio generate the server, and see how we can interact with it. WCF allows us to create applications that communicate remotely with one another - for instance, a client can call a method on a remote server and obtain the result. To follow along, you'll need a version of Visual Studio from 2008 onwards. Sadly, you can't do this in SharpDevelop.

To start off, set up a new WCF Service Library:


You'll notice that Visual Studio has generated some files for us, but let's worry about those later. For now, press F5. When you do that, this program comes up:


This WCF Test Client is actually a program that is communicating with our service (the one autogenerated by Visual Studio). We can see that there is this service at a particular URL on localhost:8733. This service is exposing a couple of methods, one of which is GetData(). Both methods are part of an interface (called a contract) called IService1. If you double-click on GetData(), you can see a Request section at the top, which shows the input parameters it can take.

Let's change the Value of the value parameter from 0 to 35, and then hit the Invoke button. If you get the following security warning, just click OK:


Once you click Invoke, the Response section at the bottom shows the return value, and echoes your input:


Let us now take a look at how this works. Our service exposes the two methods we have seen via the IService1 interface, and the Service1 class which implements it:


Notice how the IService1 interface is adorned with the ServiceContract attribute, and its methods are adorned with the OperationContract. That's how a WCF service exposes its functionality; a client will talk to the server through this interface. We'll see that in a moment. But first, let's take a look at how the service is configured. If you open the App.config file, you'll notice there is quite a bit of configuration in there:


The important things to notice at this stage are the base address and the endpoints. The base address shows the URL where the service is being hosted, and it's the same URL that clients will connect to. The endpoints, on the other hand, define how clients will connect to the service. In this case we have two endpoints: a basic HTTP binding which is used when a client connects to the base address, and which uses the IService1 interface as a contract. If you read more about WCF, you'll find these endpoints referred to as ABC (address, binding, contract). The other endpoint, mex, is a metadata exchange feature by which clients can discover what a server has to offer - that's how the WCF Test Client we used earlier manages to discover the functionality offered by our service.

If you are thinking that the configuration file looks complicated, that's understandable. Fortunately, however, you don't have to edit it by hand. If you right click on App.config, and select Edit WCF Configuration...


...then you can use this handy editor to set things up as you like:


When you press F5 and run the service, it's actually being hosted inside this WCF Service Host, that you can access from the System Tray:


The WCF Test Client, on the other hand, is being invoked via a command line argument. You can see this if you right click on the project, select Properties, and then select the Debug tab, you'll see the following:


Now, let's see how we can actually communicate with our service without using the WCF Test Client. First, copy the service URL (by default it's http://localhost:8733/Design_Time_Addresses/CsWcfMinimal/Service1/). Add a new project (Console Application) to the solution; this project will act as the client. Once that is done, right click on References and select Add Service Reference...:


Enter the service URL in the Address field and hit Go:


Notice the Namespace field is set to ServiceReference1 by default - we'll use this in a minute to identify the service from the client code. Press OK. This generates a bunch of code in the background that makes life easier for the client. In fact, let us now write some code in the client's Main() method to use the service. We start off by creating a client using the code generated by the service reference:

            ServiceReference1.IService1 service = new ServiceReference1.Service1Client();

If you click on Service1Client() and press F12 (Go to Definition), you'll be able to see the service reference code that was so conveniently generated for you:


...and if you open the client's App.config file, you'll see that the endpoint has been set up for us:


Let's get back to the code. All we have left to do is use the methods we want to use. Here's the full code for the client's Main() method:

        static void Main(string[] args)
        {
            ServiceReference1.IService1 service = new ServiceReference1.Service1Client();
            String response = service.GetData(5);
            Console.WriteLine(response);

            Console.ReadLine();
        }

Now, since the service is still your startup project, press Ctrl+F5 to run it without debugging. Once that is up and running, start the client either via the appropriate context menu option (see screenshot below), or by setting it up as the startup project and then pressing F5.


Rejoice, for it works:


Lovely! :) In this article, we explored the sample WCF Service Library project that is provided when you start a new project of that type. We saw how it is hosted in the WCF Service Host, and how we can interact with it via the WCF Test Client, which is launched by means of a command line argument. We also learned how to consume it from a client program, by first adding a service reference based on the service URL, and then using the handy autogenerated code to invoke the methods on the service.

We didn't actually make any funky server functionality though - we simply used that provided in the project. If you want to try your hand at writing your own service, Mahak Gupta's "A Simple Example of WCF Service" is a great article showing how you can make a simple WCF calculator service.