⬆️ ⬇️

A simple example of using WCF in Visual Studio 2010. Part 1

You are expected in two parts:







It's been a long time since I wrote the original post. A simple example of using WCF . That was before the release of Visual Studio 2008, and much has changed since then. Since many people still ask questions in the comments to that post, let's see what we currently have to do in order to raise and start the service (service), as well as access it from the client application.



This time we will start with the class library assembly (DLL), and we will also deploy the service inside the console application. The client will again use the Windows Forms application. Although we do everything in Visual Studio 2010, much of it also applies to VS2008. I will mention when it will be wrong and will offer an alternative option. This time I will describe in a little more detail what we have to do, so this post will be a little more than the original one.



Creating a project



First create a new class library where we define the service itself. Select New Project and Class Library as the project template. Enter the name of the project “EmailService” and the name of the solution “WCFSimpleExample2010”. If you cannot set a name for the solution, check whether the option Create directory for solution is selected.

')





Creating a contract



First, we will create a contract with only one method, or an operation, as they are called in WCF. Rename the file to IEmailValidator.cs and create an interface with the same name.

Now add the signature of the ValidateAddress method, which takes a single EmailAddress argument of type string and returns a boolean value. This is a simple interface, nothing complicated.

public interface IEmailValidator { bool ValidateAddress( string emailAddress); } * This source code was highlighted with Source Code Highlighter .
  1. public interface IEmailValidator { bool ValidateAddress( string emailAddress); } * This source code was highlighted with Source Code Highlighter .
  2. public interface IEmailValidator { bool ValidateAddress( string emailAddress); } * This source code was highlighted with Source Code Highlighter .
  3. public interface IEmailValidator { bool ValidateAddress( string emailAddress); } * This source code was highlighted with Source Code Highlighter .
  4. public interface IEmailValidator { bool ValidateAddress( string emailAddress); } * This source code was highlighted with Source Code Highlighter .
public interface IEmailValidator { bool ValidateAddress( string emailAddress); } * This source code was highlighted with Source Code Highlighter .


Now we have to tell WCF that this is our contract. We do this by adding attributes, but first we must add a reference to System.ServiceModel. Right-click on the project and select Add reference , then select System.ServiceModel from the list. I use Visual Studio 2010 Pro Power Tools , so my image in the screenshot may be different from yours, but the idea is the same.











Now you can add attributes to the interface. Above the interface definition, place the ServiceContract attribute and, on the operation, the OperationContract attribute. Add the using System.ServiceModel directive at the very beginning of the code file, or let Visual Studio do it for you when you hover over one of the attribute names. If you entered it correctly and are case sensitive, you can press CTRL +. and then the context menu appears, which allows you to add the using directive automatically. As a result, your interface should look like this:

  1. [ServiceContract]
  2. public interface IEmailValidator
  3. {
  4. [OperationContract]
  5. bool ValidateAddress ( string emailAddress);
  6. }
* This source code was highlighted with Source Code Highlighter .




Create service implementation



Now that we have a contract, we need to write code for the service in order to actually do what we want to do. Create a new class that implements the interface. We will use a regular expression to verify the email address and, if correct, return true. You must either type something like the following code, or write your own. :-)

  1. public class EmailValidator: IEmailValidator
  2. {
  3. public bool ValidateAddress ( string emailAddress)
  4. {
  5. Console .WriteLine ( "Validating: {0}" , emailAddress);
  6. string pattern = @ "^ ([0-9a-zA-Z] ([-. \ w] * [0-9a-zA-Z]) * @ (([0-9a-zA-Z]) + ( [- \ w] * [0-9a-zA-Z]) * \.) + [a-zA-Z] {2.9}) $ " ;
  7. return Regex.IsMatch (emailAddress, pattern);
  8. }
  9. }
* This source code was highlighted with Source Code Highlighter .


You now have the two most important classes for your service. It’s not really necessary to use the interface, but this is best practice. Thus, you can inherit several interfaces, as well as implement different versions of interfaces.



Creating a host



As already mentioned, we will use a console application as a host. Add a new project and now choose Console Application as the project template. Call it "ConsoleHost".







Add the link to System.ServiceModel again, as well as to the EmailService project. In your Main method, create a ServiceHost object and pass it the correct arguments in the constructor, as shown below.

  1. Type serviceType = typeof (EmailValidator);
  2. Uri serviceUri = new Uri ( "http: // localhost: 8080 /" );
  3. ServiceHost host = new ServiceHost (serviceType, serviceUri);
  4. host.Open ();
* This source code was highlighted with Source Code Highlighter .


In line 4, we create a ServiceHost object. As the first argument, it gets the implementation type of our service. And the base address as the second argument. You can read more about base addresses here and more about placing here . The type is defined in line 1, the base address is in line 2. Finally, in line 5, our host is started.



WCF4: Standard Endpoints



This is already a feature of the .NET Framework 4.0 and this cannot be done in the previous version of .NET. Standard endpoints are a new feature designed to make configuring your service less troublesome. I would like to explicitly define everything in detail, so that everyone knows what is happening. But in our example, everything works very well. If you do not use. NET 4.0, you can no longer read and go to the second part , which will be published later.

You can add standard endpoints yourself by adding host.AddDefaultEndpoints (); to the code, right before the host.Open (); line.

How can we see that endpoints are configured by default? I have a small script from the distant past that displays everything that is currently running. I will not go into details, just paste the following lines of code after host.Open () ;.

  1. #region Output dispatchers listening
  2. foreach ( Uri uri in host.BaseAddresses)
  3. {
  4. Console .WriteLine ( "\ t {0}" , uri.ToString ());
  5. }
  6. Console .WriteLine ();
  7. Console .WriteLine ( "Number of dispatchers listening: {0}" , host.ChannelDispatchers.Count);
  8. foreach (System.ServiceModel.Dispatcher.ChannelDispatcher dispatcher in host.ChannelDispatchers)
  9. {
  10. Console .WriteLine ( "\ t {0}, {1}" , dispatcher.Listener. Uri .ToString (), dispatcher.BindingName);
  11. }
  12. Console .WriteLine ();
  13. Console .WriteLine ( "Press <ENTER> to terminate Host" );
  14. Console .ReadLine ();
  15. #endregion
* This source code was highlighted with Source Code Highlighter .


Now you have the opportunity to see the endpoints, as in the first screenshot below. You can use the browser to go to the service URI and look at the standard MEX endpoint .











As you can see, this tells us that the MEX endpoint (aka metadata) is not yet configured. Now there is an easy way to do this through the new standard endpoints. My first impression was that it would work.

  1. Type serviceType = typeof (EmailValidator);
  2. Uri serviceUri = new Uri ( "http: // localhost: 8080 /" );
  3. ServiceHost host = new ServiceHost (serviceType, serviceUri);
  4. host.AddDefaultEndpoints ();
  5. // This actually doesn’t just simply work.
  6. host.AddServiceEndpoint ( new ServiceMetadataEndpoint ());
* This source code was highlighted with Source Code Highlighter .


In line 5, you see that we add standard endpoints, and in line 7 we add a ServiceMetadataEndpoint or MEX endpoint. Unfortunately, the metadata behavior cannot be added by itself, so you still have to do it yourself. Another way is to specify in the configuration that you want to include metadata. Another new feature in WCF4 is the ability to inherit configurations. You can specify in machine.config or in your local configuration what should be enabled by default for WCF services. I recommend that you do not do this in machine.config, but this is just my opinion. This is how I implemented this in the configuration of my project, the app.config file of our console host application. I would like to draw your attention to the fact that in the next part we will do it in the old manner, in a way that will work in Visual Studio 2008 and which I myself prefer.

  1. <? xml version = "1.0" encoding = "utf-8" ? >
  2. < configuration >
  3. < system.serviceModel >
  4. < behaviors >
  5. < serviceBehaviors >
  6. < behavior >
  7. < serviceMetadata httpGetEnabled = "True" />
  8. </ behavior >
  9. </ serviceBehaviors >
  10. </ behaviors >
  11. </ system.serviceModel >
  12. </ configuration >
* This source code was highlighted with Source Code Highlighter .


As you can see, I did not specify a name for the behavior, in WCF4 this means that it will be used by all services. It also means that each service needs a base address for HTTP endpoints.

For reference, here is the code for our console host application:

  1. static void Main ( string [] args)
  2. {
  3. Type serviceType = typeof (EmailValidator);
  4. Uri serviceUri = new Uri ( "http: // localhost: 8080 /" );
  5. ServiceHost host = new ServiceHost (serviceType, serviceUri);
  6. host.Open ();
  7. #region Output dispatchers listening
  8. foreach ( Uri uri in host.BaseAddresses)
  9. {
  10. Console .WriteLine ( "\ t {0}" , uri.ToString ());
  11. }
  12. Console .WriteLine ();
  13. Console .WriteLine ( "Number of dispatchers listening: {0}" , host.ChannelDispatchers.Count);
  14. foreach (System.ServiceModel.Dispatcher.ChannelDispatcher dispatcher in host.ChannelDispatchers)
  15. {
  16. Console .WriteLine ( "\ t {0}, {1}" , dispatcher.Listener. Uri .ToString (), dispatcher.BindingName);
  17. }
  18. Console .WriteLine ();
  19. Console .WriteLine ( "Press <ENTER> to terminate Host" );
  20. Console .ReadLine ();
  21. #endregion
  22. }
* This source code was highlighted with Source Code Highlighter .




Accessing Metadata



Now we can open Internet Explorer or any other browser, start our console application host (otherwise, the endpoints will not be available) and go to the URI of our service: http: // localhost: 8080 /

If you see a screen with a link to WSDL, most likely you coped with the creation of the service.



Creating a client application



Now we will add another project that will access the service, and we will have the opportunity to check whether the specified email addresses are valid, or at least satisfying our regular expression.

Add a new console application and this time name it ConsoleClient. Make sure that your service (host) is running, and it does not work in debug mode. The easiest way is to install the ConsoleHost project as a start project and press CTRL + F5 to start it not in debug mode.

Now we need a proxy class (proxy class), which will be between our client and service. There are two ways to create proxies for our service. I prefer to do it manually to know exactly what is happening. I will show it first.



Manual proxy creation



First, run the Visual Studio 2010 command line (or Visual Studio 2008) and navigate to the ConsoleClient location. Since this is a Visual Studio command line, you should have access to the svcutil.exe proxy generator. Enter the following command:

svcutil http://(___)localhost:8080/ /o:ServiceProxy.cs /config:App.Config /n:*,ConsoleClient



This command should generate two files: a proxy service and an application configuration file. Return to Visual Studio to your ConsoleClient application. In order for App.Config and ServiceProxy.cs to become available, you need to click the icon at the top of the Solution Explorer , as shown in the screenshot below. Now new files are displayed and you can include them in the project.

Note: the screenshot in the console window shows the wrong namespace ConsoleHost instead of ConsoleClient.










When we started svcutil.exe we passed to it as the first argument the location of our service, as indicated in the host. This is the base address. The second argument is our proxy. The third argument indicates that we also want to update the configuration of the application, and if it is not available, create it. The final argument is the namespace for our proxy, which is currently the same as our application.



Service call



Now we can finally turn to the service. Go to the Main method in the Program class again. Now we have access to the proxy class, which has the name of our service with the suffix Client . In this case, EmailValidatorClient .

  1. EmailValidatorClient svc = new EmailValidatorClient ();
  2. bool result = svc.ValidateAddress ( "dennis@bloggingabout.net" );
* This source code was highlighted with Source Code Highlighter .


In line 1 you can see the initialization of the proxy. This does not mean setting up a connection, it will occur on the first call. In line 2, the service is called and the result is returned.

Below is the code of our Main method, which will request email addresses.

  1. static void Main ( string [] args)
  2. {
  3. while ( true )
  4. {
  5. Console .WriteLine ( "Enter an email address or press [ENTER] to quit ..." );
  6. string emailAddress = Console .ReadLine ();
  7. if ( string .IsNullOrEmpty (emailAddress))
  8. return ;
  9. EmailValidatorClient svc = new EmailValidatorClient ();
  10. bool result = svc.ValidateAddress (emailAddress);
  11. Console .WriteLine ( "Email address is valid: {0}" , result);
  12. }
  13. }
* This source code was highlighted with Source Code Highlighter .




Creating a proxy through Visual Studio, the easy way.



Instead of creating a proxy service manually using svcutil.exe, you can also let Visual Studio create it for you. Just right-click on the project and select “Add Service Reference ...”. A dialog box will appear where you will need to enter your service address and namespace.







Now we are in the ConsoleClient namespace, but it also unites already existing namespaces. So now you can access EmailValidatorClient via ConsoleClient.EmailValidatorClient . And this is one of the reasons why I don’t like to use the automatically generated proxy class. Now you must remember to add a using directive for this namespace. Probably the best solution in the dialog box is to specify the namespace of Proxies or something similar, so that the full namespace name makes more sense.



Client launch



If the service is still running (if not, restart it), you can right-click on the ConsoleClient project and select Debug and Start new instance . That's it, you're done.



What's next?



Next, I will explain how to manually add endpoints and how to host services in IIS. You can read about it here .



From here you can download a solution for Visual Studio 2010 . In the next part, a solution for Visual Studio 2008 will also be available.

Source: https://habr.com/ru/post/116764/



All Articles