饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 101 页

作者:Nick Randolph/等 当前章节:15445 字 更新时间:2026-6-18 14:51

among applications, including (but not limited to) remoting, web services, and a myriad of

networking protocols. This has often frustrated application developers who not only had to

pick the appropriate technology to use, but also had to write plumbing code that would allow

their applications to use different technologies depending on where or how they would be

deployed. For example, when users are connected directly to the intranet it is probably better

for them to use a remoting or direct TCP/IP connection for their speed benefits. However,

these aren’t the ideal solution for communication when the application is outside the corporate

firewall, in which case a secured web service would be preferable.

682 .

chaPter 31 WindoWS communicATion FoundATion (WcF)

WCF is designed to solve this sort of problem by providing a means to build messaging applications

that are technology-agnostic, which can then be configured (in text-based configuration files) to

what technologies each service will support and how they will be used. Therefore, you only need

to write the one service and it can support all the various communication technologies supported by

WCF. WCF is essentially a unified communication layer for .NET applications.

GettinG started

A WCF service can be added to an existing project (such as a web application), or it can be created

as a standalone project. For the purposes of this example you will be creating a standalone service

so you can easily see how a single service can be configured and hosted in many communication

scenarios.

When you open the New Project dialog and click the WCF category (under either the VB or C#

languages), you will notice a number of different WCF project types as shown in Figure 31-1.

fiGure 31-1

The WCF Workflow Service Application project template provides an easy way to expose a

Windows Workflow (WF) publicly, and this is discussed in Chapter 32. The Syndication Service

Library project template is used to expose data as an RSS feed. However, the project template you

will be using in the example for in this chapter is the WCF Service Library project template.

If you look in the Web category in the New Project dialog, you will see that

there is also a WCF Service Application project template, which wasn’t under

the WCF category. This project template creates a WCF service that is already

configured to be hosted within an ASP.NET web application.

Defining Contracts .

683

By default, a new WCF Service Library will include IService1.vb and Service1.vb (or .cs if you

are using C#), which define the contract and the implementation of a basic service, respectively.

When you open these files you will see that they already expose some operations and data as an

example of how to expose your own operations and data yourself. This can be all cleared out until

you simply have an interface with nothing defined (but with the ServiceContract attribute left in

place), and a class that simply implements that interface. Or you can delete both files and start anew.

When you want to add additional services to your project you will find a WCF Service item template

in the Add New Item dialog that will add both an interface and a class to your project to use for the

contract and implementation of the service.

defininG contracts

This example project will expose some data from the Entity Framework model that you created in

Chapter 29 for the AdventureWorksLT database, and expose some operations that can be performed

on that data. The way that you do so is by creating contracts that will define the operations and

the structure of the data that will be publicly exposed. Three core types of contracts exist: service

contracts, data contracts, and message contracts.

.

A service contract is a group of operations, essentially detailing the capabilities of the service.

.

A data contract details the structure of the data being passed between the service and the client.

.

A message contract details the structure of the messages passed between the service and the

client. This is useful when the service must conform to a given message format. This is an

advanced topic, and not required for basic services, so we won ’t cover this type of contract in

this chapter.

These contracts are defined by decorating the classes/interfaces in the service with special attributes.

In this chapter you walk through an example of creating a WCF service exposing customer data from

the AdventureWorksLT database to client applications. To do this you will expose operations for

working with the customer data, which will expose the actual customer data itself in the database.

For the purpose of this example you’ll start fresh — so delete IService1

(.vb or .cs) and

Service1

(.vb or .cs). Add a new item to the project using the WCF Service item template,

called CustomerService. This will add two new files to your project — CustomerService

(.vb

or .cs) and ICustomerService

(.vb or .cs).

There are two primary angles that you can take when designing services. You

can take either an implementation-first approach (where you write the code first

and then apply attributes to it to create the contract), or you can take a contract-

first approach (where you design the schema/WSDL first and generate the code

from it). An in-depth discussion of these approaches is beyond the scope of

this chapter; however, WCF can support both approaches. The example in this

chapter follows the contract-first approach.

684 .

chaPter 31 WindoWS communicATion FoundATion (WcF)

creating the service contract

Focus on defining the service contract first. The operations you want to expose externally are:

.

AddCustomer

.

GetCustomer

.

UpdateCustomer

.

DeleteCustomer

.

GetCustomerList

You may recognize the first four operations as standard CRUD (Create, Read, Update, and

Delete) operations when you are working with data. The final operation will return a list of all the

customers in the database.

Now that you know what operations are required you can define your service contract.

You may have noted from the sample implementation in the WCF project

template that all of the service attributes were defined in the interface. However,

creating an interface to decorate with the contract attributes is not essential — in

fact, you don’t need to create an interface at all, and you can decorate the class

itself with the attributes instead. However, standard practice (and best practice)

dictates that the contract should be defined as (and in) an interface, so you will

be following this best practice in the example.

You will define your operations in the ICustomerService interface. However, these operations will

expose data using a data class that you haven’t defined as yet — in the meantime, create a stub

data class and you can flesh it out shortly. Add a new class to the project called CustomerData

and leave it as it is to act as your stub. Each of the operations needs to be decorated with the

OperationContract attribute:

Vb

< ServiceContract([Namespace]:="http://www.professionalvisualstudio.com") >

Public Interface ICustomerService

< OperationContract() >

Function AddCustomer(ByVal customer As CustomerData) As Integer

< OperationContract() >

Function GetCustomer(ByVal customerID As Integer) As CustomerData

< OperationContract() >

Sub UpdateCustomer(ByVal customer As CustomerData)

< OperationContract() >

Sub DeleteCustomer(ByVal customerID As Integer)

< OperationContract() >

Defining Contracts .

685

Function GetCustomerList() As List(Of CustomerData)

End Interface

c#

[ServiceContract(Namespace="http://www.professionalvisualstudio.com")]

public interface ICustomerService

{

[OperationContract]

int AddCustomer(CustomerData customer);

[OperationContract]

CustomerData GetCustomer(int customerID);

[OperationContract]

void UpdateCustomer(CustomerData customer);

[OperationContract]

void DeleteCustomer(int customerID);

[OperationContract]

List<CustomerData> GetCustomerList();

}

Both the ServiceContract and OperationContract attributes have a number of properties that

you can apply values to, enabling you to alter their default behavior. For example, both have a name

property (enabling you to specify the name of the service/operation as seen externally). Of particular

note is the ServiceContract’s Namespace property, which you should always explicitly specify

(as has been done in the preceding code). If a namespace has not been explicitly set, the schema

and WSDL generated for the service will use http://tempuri.org as its namespace. However, to

reduce the chance of collisions with other services it’s best to use something unique such as your

company’s URL.

Now that you’ve defined your contract you need to actually implement these operations. Open the

CustomerService class, which implements the ICustomerService interface. VB will implement

the methods automatically (you may need to press Enter after the Implements ICustomerService

for these to actually be implemented), and in C# you can use the smart tag (Ctrl+.) to have the

methods automatically implemented. The service contract is now complete and ready for the

operations to be implemented (that is, write the code that performs each operation). However, before

you do so you still need to define the properties of the data class, and at the same time you should

also define the data contract.

creating the data contract

You are returning objects containing data from some of the operations you expose in your service,

and accepting objects as parameters. Therefore, you should specify the structure of these data

objects being transferred by decorating their classes with data contract attributes.

686 .

chaPter 31 WindoWS communicATion FoundATion (WcF)

From the .NET Framework 3.5 SP1 onward it is no longer essential that you

explicitly define a contract for your data classes if the classes are public and each

has a default constructor (this is referred to as having an inferred data contract

instead of a formal data contract). However, it is useful (and recommended)

to create a formal contract anyway — especially if you need to conform to a

specific message format in your communication, have non-.NET clients access

your service, or want to explicitly define what properties in the data class

are included in the message. Because explicitly specifying the data contract is

generally recommended, this is the approach you will be taking in the example.

This example requires only one data class — the CustomerData class that you already created

(although no properties have been defi ned on it as yet), which you will now decorate with the data

contract attributes. Whereas the service contract attributes were found in the System.ServiceModel

namespace, data contract attributes are found in the System.Runtime.Serialization namespace,

so C# developers will need to start by adding a using statement for this namespace in their classes:

using System.Runtime.Serialization;

Each data class first needs to be decorated with the DataContract attribute, and then you can

decorate each property to be serialized with the DataMember attribute:

Vb

< DataContract([Namespace]:="http://www.professionalvisualstudio.com") >

Public Class CustomerData

< DataMember() > Public Property CustomerID As Integer

< DataMember() > Public Property Title As String

< DataMember() > Public Property FirstName As String

< DataMember() > Public Property MiddleName As String

< DataMember() > Public Property LastName As String

< DataMember() > Public Property Suffix As String

< DataMember() > Public Property CompanyName As String

< DataMember() > Public Property EmailAddress As String

< DataMember() > Public Property Phone As String

End Class

c#

[DataContract(Namespace="http://www.professionalvisualstudio.com")]

public class CustomerData

{

[DataMember] public int CustomerID { get; set; }

[DataMember] public string Title { get; set; }

[DataMember] public string FirstName { get; set; }

[DataMember] public string MiddleName { get; set; }

[DataMember] public string LastName { get; set; }

[DataMember] public string Suffix { get; set; }

[DataMember] public string CompanyName { get; set; }

[DataMember] public string EmailAddress { get; set; }

[DataMember] public string Phone { get; set; }

}

If you don ’ t want a property to be serialized, simply don ’ t apply the DataMember attribute to it. Like

the service contract attributes you can also set the value of each of the various properties each attribute

has. For example, the DataContract attribute enables you to set properties such as the namespace

for the class ’ s data contract (the Namespace property), and an alternative name for the class ’ s data

contract (the Name property). The DataMember attribute also has a number of properties that you

can set, such as the member ’ s name (the Name property), and whether the member must have a value

specifi ed ( IsRequired ).

When defi ning your data contract you might ask why you are decorating the

data classes directly and aren ’ t defi ning the contract on an interface as you did

with the service contract (which was considered good practice). This is because

only concrete types can be serialized — interfaces cannot (and thus cannot be

specifi ed as parameter or return types in WCF calls). When an object with only

an interface specifying its type is to be deserialized, the serializer would not

know which type of concrete object it should create the object as. There is a

way around this but it ’ s beyond the scope of this chapter. Note that if you try

to create an interface and decorate it with the DataContract attribute, this will

generate a compile error.

You must be aware of some caveats when designing your data contracts. If your data class inherits

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页