Code Tips

Web Services Software Factory (5 of 5)

Note: All links current as of the time of this blog post

We have landed. This is tutorial part 5 of 5. In parts 1-4 (part 1 starts here) we created a web service that does some simple encryption, decryption, and hashing. Before beginning this part of the tutorial, please create a virtual directory in IIS pointing to the Web Service project that you set up in part 4 and make it a .Net application. I named the virtual directory CryptService and as such I can browse to http://localhost/CryptService/CryptService.svc and see the service.

Create a new C# Console Application. I named my application TestCryptService. Right click on your project in solution explorer and select “Add Service Reference”. Put your URL to your service in and click Go. After a few moments, you should see what was discovered about your service. Change the namespace to CryptService and click Ok.
Add Service Reference to Project

Notice that all of the binding information has been added to your app.config. If you look at the endpoint section, you will see that /basic was added to the end of the CryptService.svc. I mentioned last time that that allows you to create multiple endpoints to the same point, and just use different bindings, etc.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="Crypt" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/CryptService/CryptService.svc/basic"
                binding="basicHttpBinding" bindingConfiguration="Crypt" contract="CryptService.CryptService"
                name="Crypt" />
        </client>
    </system.serviceModel>
</configuration>

Now, within the Program.cs file that was created for you, enter in this code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestCryptService.CryptService;

namespace TestCryptService
{
    class Program
    {
        static void Main(string[] args)
        {
            TestDesEncryption();
            TestRijndaelEncryption();
            TestMd5Hash();
            TestSha256Hash();
        }

        /// <summary>
        /// This method is the only one that is commented.  All of the other methods function 
        /// in exactly the same way.  The only reason they are included is for completeness, 
        /// so that all of our server methods are hit.
        /// </summary>
        static void TestDesEncryption()
        {
            // The CryptServiceClient is the proxy created automatically for you.
            // It would be called CryptServiceClient whether you used svcutil.exe 
            // yourself or you added a service reference.
            CryptServiceClient client = new CryptServiceClient();
            

            EncryptionObject encryptionObject = new EncryptionObject();

            encryptionObject.EncryptionAlgorithm = EncryptionAlgorithm.DES;
            encryptionObject.Text = "Testing our DES Encryption";

            // Call the EncryptString method and get back our encrypted value
            string encryptedText = client.EncryptString(encryptionObject);

            encryptionObject = new EncryptionObject();
            encryptionObject.EncryptionAlgorithm = EncryptionAlgorithm.DES;
            encryptionObject.Text = encryptedText;

            // Call the DecryptString method and get back our plain text
            string plainText = client.DecryptString(encryptionObject);

            // Output the values and see what we get.
            Console.WriteLine("-- DES --");
            Console.WriteLine("Encrypted Text: {0}", encryptedText);
            Console.WriteLine("Plain Text: {0}", plainText);
            Console.WriteLine();
        }

        static void TestRijndaelEncryption()
        {
            CryptServiceClient client = new CryptServiceClient();
            EncryptionObject encryptionObject = new EncryptionObject();

            encryptionObject.EncryptionAlgorithm = EncryptionAlgorithm.Rijndael;
            encryptionObject.Text = "Testing our Rijndael Encryption";

            string encryptedText = client.EncryptString(encryptionObject);

            encryptionObject = new EncryptionObject();
            encryptionObject.EncryptionAlgorithm = EncryptionAlgorithm.Rijndael;
            encryptionObject.Text = encryptedText;

            string plainText = client.DecryptString(encryptionObject);

            Console.WriteLine("-- Rijndael --");
            Console.WriteLine("Encrypted Text: {0}", encryptedText);
            Console.WriteLine("Plain Text: {0}", plainText);
            Console.WriteLine();
        }

        static void TestMd5Hash()
        {
            CryptServiceClient client = new CryptServiceClient();
            HashObject hashObject = new HashObject();

            hashObject.HashType = HashType.MD5;
            hashObject.StringToHash = "Some string to hash";

            string md5Hash = client.HashString(hashObject);

            Console.WriteLine("-- MD5 Hash --");
            Console.WriteLine("Original String: {0}", hashObject.StringToHash);
            Console.WriteLine("Hashed Value: {0}", md5Hash);
            Console.WriteLine();
        }

        static void TestSha256Hash()
        {
            CryptServiceClient client = new CryptServiceClient();
            HashObject hashObject = new HashObject();

            hashObject.HashType = HashType.SHA256;
            hashObject.StringToHash = "Some string to hash";

            string shaHash = client.HashString(hashObject);

            Console.WriteLine("-- Sha256 Hash --");
            Console.WriteLine("Original String: {0}", hashObject.StringToHash);
            Console.WriteLine("Hashed Value: {0}", shaHash);
            Console.WriteLine();
        }
    }
}

When I run this code, I see this output:
Test Console Output

That is IT! If you’ve made it this far and see that output, you are done. You are now ready to use the Web Services Software Factory to make web services yourself. As always, if you didn’t get these results, double check your steps and if you are still having problems, leave me a comment and I will try to help you.

All code was written as throwaway code, so I realize that it could use some refactoring and some optimization. The point of this tutorial was to expose you to using the WSSF in more than a “Hello World” kind of way and to at least mimic the real world with something a little bit fun.

17 comments Web Services Software Factory (5 of 5)

B Cahillane says:

Do you have the completed solution available for download?

ManjuHanzan says:

Great Tutorial on WSSF. a must read for any one who is using this..

But I am developing a silverlight application( 4 layered arcgitecture UI, Service layer, Business layer, DAL)

So my concern is
how to use WSSF in application such as this.

Pete says:

Manju,

Creating and using services is very important for people creating Silverlight applications. All contact with a database in a web-based silverlight application (as opposed to the new piece in Silverlight 3 that lets you run Silverlight “out of the browser”) should be through a web service.

Remember that Silverlight applications are downloaded to every client as a .xap file. People can unzip and use reflector on those files to see all of your logic, connection strings, etc. If you break out the logic that is proprietary and unique to your application and your actual data access (code hitting the db directly) to the service, you will be in a lot better shape.

You could use the WSSF to create the service, and then let Silverlight consume the service. Just remember to add the right security around the service calls or you’ve gained nothing by the exercise.

Best of luck.

ManjuHanzan says:

Thank you very much for your reply.
I am using Entity Framework in DAL.
I understand that we can create /have customaise a Data Access Layer using WSSF.
So Can we have all layers (except UI) just using WSSF?
Please give your comments.

Pete says:

Manju,

Your UI in a fully designed Silverlight application will have 3 layers the Model, the View, and the ViewModel (MVVM Pattern). Your model will allow access to your WCF service (treating it like a database, etc, since the service is how you persist and retrieve data).

Additionally, within your WCF service (created with WSSF) you will have all the layers that I’ve described in this tutorial.

Marinho says:

Do you have a complete solution available for download?

Dejan says:

Thank you for the tutorial; It was probably the most informational article on the matter I have seen so far.

I would also really like to see the whole solution posted if possible.
Main reason is that somewhere in the part 3 some elements started missing; there was no base class provided for the service implementation (CryptServiceBase), message contracts namespace is unavailable etc. Posting the whole solution would have cleared ambiguities.

Chinmay says:

This is gr8. I was looking for a doc like this.. Really gr8.
Can you please send me some other documents which have WSSF basics.
If you also can explain a little bit about fault contracts and Enumeration Datacontract translator then it would be gr8

[…] the right virtual directory for the service for the console application to run (as described in part 5 of the tutorial), but other than that, this should be all you need… binaries are even […]

Pete says:

cheers Pete for this tutorial. It is of great help.
I was successfully able to create complete project with your 5step-5page blog. Thanks :).

Elvis Furtado says:

Fantastic article!! I was just starting to wonder how a team oer here had ended up generalizing a large set of ASMX services into WCF equivalents in less than a month and voila!! you answered it…

Thanks to you, I am the local hero for cracking this case!! thanks again Pete!!

Elvis

Pete says:

Elvis,

Wow, that is high praise indeed. Very glad I could help. Thanks for the comment.

Ai says:

Hi Pete,

Thank you for a nice article.
How would you enable authentication for a client
that would make a series of calls to your WCF services in succession?

best regards,
Ai

Pete says:

Ai,

You have a couple of options. The two best ways are as follows:

1. If this is a Windows Client, you could mark the service to use Windows Authentication and then the service wouldn’t have to do to much extra special processing.

2. If this is a web client, you can call the service for an authentication method and return a token. After that, you can have every method require that token as a parameter, then you validate the token on each call.

Elvis Furtado says:

Its been years since I came back to your blog. I remember using the information you presented here which really helped shape my career at that point in time.

Apparently another commentor Ravi Santlani, who happened to comment a few months before I did in 2010, is today in the same company as I am.

Small world ain’t it! 🙂

Pete says:

That’s awesome, Elvis. You don’t know how happy I am that something I wrote was of any help to you at all. That’s also pretty great that Ravi and you work at the same place. The development world is indeed very small!

Leave a Reply

Your email address will not be published. Required fields are marked *