官术网_书友最值得收藏!

Consuming WCF services

Now comes the most important part: using the service! How you go about consuming a WCF service depends greatly on the type of client application used.

Non-WCF clients

If you plan on calling a WCF service from a non-WCF client, have no fear, you're still in great shape. One of the design goals of WCF (and any quality SOA solution) is interoperability, which means that WCF services should be consumable on a wide variety of platforms and technology stacks.

Now, it is still the responsibility of the service designer to construct a service that's usable by non-WCF applications. For instance, a broadly used service would offer basicHttpBinding to ensure that applications based on .NET Framework 2.0, or JRE 1.4 would have no problem consuming it. An interoperable service would also use security schemes that rely upon commonly available certificates for transport security.

Let's assume that a WCF service with a basic HTTP endpoint has been exposed. Let's also assume that this service has a metadata "behavior" attached to it so that we can interrogate its WSDL contract. If you have a .NET Framework 2.0 application that typically consumes classic ASMX services (ASP.NET web services), they can consume a WCF service in the exact same fashion. That is, add a new web reference to the WCF service metadata definition.

If you have Visual Studio 2012 installed, the Add Web Reference option isn't immediately available on the project.

  1. You first right-click the project and choose the Add Service Reference menu item. Click on the button labeled Advanced, which you'll find at the bottom of the window:
  2. The next window that opens is a settings window, which has a button at the bottom for those who wish to add a traditional "web reference" that leverages older .NET technology:
  3. Choosing the Add Web Reference button finally opens up the traditional service browser, where we plug in the URL of our service and see the corresponding metadata:
  4. In the subsequent code that calls this service, the developer would use the assigned web reference just as if they were calling any standard SOAP web service:
    Console.WriteLine("Vendor client launched ...");
    try
    {
      AsmxProxy.VendorService svc = new AsmxProxy.VendorService();
      AsmxProxy.Vendor newVendor = new AsmxProxy.Vendor();
      newVendor.VendorId = "1234";
      newVendor.VendorName = "Watson Consulting";
      newVendor.VendorContactName = "Watson Seroter";
    
      svc.InsertVendor(newVendor);
      Console.WriteLine("Vendor " + newVendor.VendorId + " inserted ...");
      Console.ReadLine();
    }
    catch (System.Web.Services.Protocols.SoapException ex)
    {
    //grab "insert fault" part of message
       Console.WriteLine(ex.Detail.InnerText);
      Console.ReadLine();
    } 

The result? The HTTP host was opened successfully by WCF, and after the client executed the insert operation, the service wrote its confirmation message to the host console:

However, if our service fails and throws our custom fault message, our client code catches it as a SOAP exception and still has access to the custom fault details. Note that the exception's detail object contains the XML message of the InsertFault type, in the following screenshot:

WCF clients

If you have the benefit of using a WCF-enabled application to call a WCF service, the full might of Microsoft's communication stack is laid before you. You are no longer constrained by HTTP-only communication and you can exploit a wide range of encoding, security, and transaction capabilities in your service consuming application.

Note

While WCF-to-WCF communication scenarios offer a rich set of communication options, technically any WS*-compliant application should be able to take advantage of a majority of WCF's service characteristics. For example, an Oracle application that understands WS-Security can effectively participate in secure conversations with a WCF service.

The easiest way to consume WCF services from a WCF application is to generate a proxy class that shields us from the plumbing necessary to call the service. A WCF proxy can be generated in one of two ways. First, we use the ServiceModel Metadata Utility tool (svcutil.exe) command-line tool if we want full control of the way the proxy class is generated. This tool takes the service metadata and generates a .NET source code file that may be used to call the WCF service.

The power in this little utility lies in the ability to apply a cornucopia of command-line parameters that define attributes of the .NET source code file, such as its programming language, namespace, output location, and a whole lot more. For instance, executing the following command on our service results in a full WCF proxy class and merges the new WCF configurations with the existing configuration file of the client application:

Svcutil.exe http://localhost:8081/VServiceBase?WSDL /      out:WCFProxy.cs /language:c#  /config:app.config /mergeConfig

Because I built the WCF service proxy manually, my client application must have both the System.ServiceModel and System.Runtime.Serialization assemblies added as project references.

Consuming the WCF proxy class looks quite similar to consuming the ASMX proxy class. In fact, the only real difference that you'll notice here is more explicit interaction with the client proxy class. Note that we work with the proxy class within a try block and catch any exceptions (including our custom one) in well-defined catch blocks. While it is tempting to apply the C# using statement to WCF proxies, that practice can actually lead to swallowed exceptions and should be avoided. See http://msdn.microsoft.com/en-us/library/aa355056.aspx for more details. The other slight difference is that the WCF proxy class has an overloaded constructor. In this case, I'm passing in the name of the service endpoint name that resides in the application configuration file:

WcfProxy.VendorServiceClient svc = new WcfProxy.VendorServiceClient ("BasicHttpBinding_VendorService");

try
  {
WcfProxy.Vendor newVendor = new WcfProxy.Vendor();
  newVendor.VendorId = "9876";
  newVendor.VendorName = "Noah Partners";
  newVendor.VendorContactName = "Noah Seroter";

  svc.InsertVendor(newVendor);

Console.WriteLine("Vendor " + newVendor.VendorId + " inserted ...");

  svc.Close();
  }
  catch (System.ServiceModel.FaultException<WcfProxy.InsertFault> ex)
    {
      Console.WriteLine(ex.Detail.FriendlyMessage);
      
      Console.ReadLine();
    }
catch (System.ServiceModel.CommunicationException) { svc.Abort(); }
catch (System.TimeoutException) { svc.Abort(); }
catch (System.Exception) { svc.Abort(); throw; }

If you're looking for an easier way to generate a WCF proxy class, look no further! Visual Studio also offers an Add Service Reference option, which enables us to generate our proxy class from within our development environment. This is depicted as follows:

By either using the ServiceModel Metadata Utility tool explicitly to generate proxy classes or, instead, using Visual Studio (which uses svcutil.exe underneath the covers), you have some efficient options for generating WCF-compliant code for use by service clients.

主站蜘蛛池模板: 崇左市| 新闻| 呼玛县| 清徐县| 奈曼旗| 静宁县| 宕昌县| 宜春市| 乌拉特中旗| 鄂伦春自治旗| 扬州市| 体育| 鄄城县| 无棣县| 奉贤区| 通州区| 乌鲁木齐县| 德州市| 峨眉山市| 昌平区| 正镶白旗| 余庆县| 富锦市| 永平县| 司法| 平湖市| 阿拉善右旗| 宜城市| 乐昌市| 黄平县| 苗栗县| 平顶山市| 光山县| 醴陵市| 安塞县| 称多县| 伊宁县| 毕节市| 聊城市| 丹东市| 平安县|