Tải bản đầy đủ - 0 (trang)
10-13. Create a SOAP-Based Web Service

10-13. Create a SOAP-Based Web Service

Tải bản đầy đủ - 0trang

CHAPTER 10 ■ NETWORKING



each of the methods you want exposed by the web service. The ServiceContractAttribute and

OperationContractAttribute classes are members of the System.ServiceModel namespace.

Define any complex data types passed to and from the service and identify them as WCF data

contracts by applying the DataContractAttribute attribute to the class and the DataMemberAttribute

attribute to the members that need to be passed across the network. The DataContractAttribute and

DataMemberAttribute classes are members of the System.Runtime.Serialization namespace.

Implement the service contract functionality by implementing the interface on a class, configure

the configuration settings that control the behavior and protocols used by the service, and host an

instance of the service class in a service host.



How It Works

WCF allows you to quickly create web services that are accessible across the Internet and that offer many

choices in terms of protocols, security, and communication models. To create a simple SOAP-based

WCF web service, you need the following key ingredients:





A service contract: This defines the functionality exposed by the web service and is

usually in the form of a C# interface, where the interface is annotated with the

ServiceContractAttribute attribute and the web service methods are annotated

with the OperationContractAttribute attribute.







A service implementation: This object implements the service contract interface

and defines what each of the web service methods does when called by a client.







A service host: The service host is a process that controls the life cycle of the web

service. This can be a custom program that loads your service (called self-hosting),

Internet Information Server (IIS), or Windows Activation Services (WAS).



There is potentially a lot of configuration information associated with a WCF web service, including

things like network addresses, protocol selection, and security settings. But the beauty of WCF is that

you really only need to worry about those bits of functionality that you are actively using and ignore the

rest. You can also choose whether to manage your configuration in code or through the application

config files. However, unless you need to make configuration decisions at runtime, it is usually best to

use declarative configuration so that you can change settings without having to change your code.

Once you have created a SOAP-based web service, the easiest way to consume it is to automatically

generate a proxy class using Visual Studio, or use the ServiceModel Metadata Utility Tool (svcutil.exe),

which is part of the Windows SDK. In some circumstances, you can also generate proxy classes

dynamically (see recipe 10-14 for details).



The Code

The following example demonstrates the creation of a simple SOAP-based web service that allows you to

create, update, find, and delete employee records. The example is self-hosted, but could be moved to IIS

or WAS without changes to the service code. The IEmployeeService interface defines the service contract.

using System;

using System.ServiceModel;

namespace Apress.VisualCSharpRecipes.Chapter10

{



527



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



[ServiceContract(Namespace = "Apress.VisualCSharpRecipes.Chapter10")]

public interface IEmployeeService

{

[OperationContract]

Employee CreateEmployee(Employee newEmployee);

[OperationContract]

bool DeleteEmployee(int employeeId);

[OperationContract(Name="GetEmployeeById")]

Employee GetEmployee(int employeeId);

[OperationContract(Name = "GetEmployeeByName")]

Employee GetEmployee(string employeeName);

[OperationContract]

Employee UpdateEmployee(Employee updatedEmployee);

}

}

Here is the class that declares the Employee data contract representing the data that is passed

between the client and the service:

using System;

using System.Runtime.Serialization;

namespace Apress.VisualCSharpRecipes.Chapter10

{

[DataContract]

public class Employee

{

[DataMember]

public DateTime DateOfBirth { get; set; }

[DataMember]

public int Id { get; set; }

[DataMember]

public string Name { get; set; }

}

}

The EmployeeService class implements the IEmployeeService interface and provides the actual logic

of the web service.

using System;

using System.Collections.Generic;

using System.Linq;

namespace Apress.VisualCSharpRecipes.Chapter10

{



528



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



public class EmployeeService : IEmployeeService

{

private Dictionary employees;

public EmployeeService()

{

employees = new Dictionary();

}

// Create an Employee based on the contents of a provided

// Employee object. Return the new Employee object.

public Employee CreateEmployee(Employee newEmployee)

{

// NOTE: Should validate new employee data.

newEmployee.Id = employees.Count + 1;

lock (employees)

{

employees[newEmployee.Id] = newEmployee;

}

return newEmployee;

}

// Delete an employee by the specified Id and return true

// or false depending on if an Employee was deleted.

public bool DeleteEmployee(int employeeId)

{

lock(employees)

{

return employees.Remove(employeeId);

}

}

// Get an employee by the specified Id and return null if

// the employee does not exist.

public Employee GetEmployee(int employeeId)

{

Employee employee = null;

lock (employees)

{

employees.TryGetValue(employeeId, out employee);

}

return employee;

}



529



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



// Get an employee by the specified Name and return null if

// the employee does not exist.

public Employee GetEmployee(string employeeName)

{

Employee employee = null;

lock (employees)

{

employee = employees.Values.FirstOrDefault

(e => e.Name.ToLower() == employeeName.ToLower());

}

return employee;

}

// Update an employee based on the contents of a provided

// Employee object. Return the updated Employee object.

public Employee UpdateEmployee(Employee updatedEmployee)

{

Employee employee = GetEmployee(updatedEmployee.Id);

// NOTE: Should validate new employee data.

if (employee != null)

{

lock (employees)

{

employees[employee.Id] = updatedEmployee;

}

}

return updatedEmployee;

}

}

}

The following code shows the simple service host created to run the service:

using System;

using System.ServiceModel;

namespace Apress.VisualCSharpRecipes.Chapter10

{

public static class Recipe10_13Service

{

static void Main(string[] args)

{

ServiceHost host = new ServiceHost(typeof(EmployeeService));

host.Open();



530



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



// Wait to continue.

Console.WriteLine("Service host running. Press Enter to terminate.");

Console.ReadLine();

}

}

}

The following shows the configuration information used by the service host:
























behaviorConfiguration="EmployeeServiceBehavior">


binding="wsHttpBinding"

contract="Apress.VisualCSharpRecipes.Chapter10.IEmployeeService" />


binding="mexHttpBinding"

contract="IMetadataExchange" />



















Finally, the following simple client code demonstrates how to interact with the service via a proxy:

using System;

using Apress.VisualCSharpRecipes.Chapter10.Services;

namespace Apress.VisualCSharpRecipes.Chapter10

{

class Recipe10_13Client

{

private static string FormatEmployee(Employee emp)

{



531



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



return String.Format("ID:{0}, NAME:{1}, DOB:{2}",

emp.Id, emp.Name, emp.DateOfBirth);

}

static void Main(string[] args)

{

// Create a service proxy.

using (EmployeeServiceClient employeeService

= new EmployeeServiceClient())

{

// Create a new Employee.

Employee emp = new Employee()

{

DateOfBirth = DateTime.Now,

Name = "Allen Jones"

};

// Call the EmployeeService to create a new Employee record.

emp = employeeService.CreateEmployee(emp);

Console.WriteLine("Created employee record - {0}",

FormatEmployee(emp));

// Update the existing Employee.

emp.DateOfBirth = new DateTime(1950, 10, 13);

emp = employeeService.UpdateEmployee(emp);

Console.WriteLine("Updated employee record - {0}",

FormatEmployee(emp));

// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter");

Console.ReadLine();

}

}

}

}



10-14. Call a WCF Service Using a Dynamically Generated

Service Proxy

Problem

You need to call the methods of a WCF service but can’t or don’t want to generate a static proxy class as

described in recipe 10-13.



532



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



Solution

If you have access to classes that represent the service and data contracts exposed by the service, you

can create a dynamic service proxy using the System.ServiceModel.ChannelFactory class.



How It Works

The ChannelFactory class is a generic class that allows you to create proxies dynamically based on WCF

service contracts. When instantiating a ChannelFactory, in addition to identifying the type of the service

proxy you want to create, you must provide details of the WCF endpoint to which you want to connect.

This includes the binding you want to use and the address of the service you want to communicate with.

Once you have instantiated a properly configured ChannelFactory, you call its CreateChannel

method, which will return a service proxy in the form of an instance of the service contract type. You can

then use this proxy to make calls against the service endpoint identified in the ChannelFactory

constructor.



The Code

The following code demonstrates the use of a dynamic service proxy to communicate with a WCF

service. The service used in this example is basically the same as that used in recipe 10-13. Instead of

using Visual Studio to generate a proxy class, the client project contains a reference to the service

project. The reference gives the client code access to the service and data contract classes of the service,

enabling the use of the ChannelFactory to create dynamic service proxies at runtime.

using System;

using System.ServiceModel;

namespace Apress.VisualCSharpRecipes.Chapter10

{

class Recipe10_14Client

{

static void Main(string[] args)

{

string serviceUri = "http://localhost:8000/EmployeeService";

// Create the ChannelFactory that is used to generate service

// proxies.

using (ChannelFactory channelFactory =

new ChannelFactory(new WSHttpBinding(), serviceUri))

{

// Create a dynamic proxy for IEmployeeService.

IEmployeeService proxy = channelFactory.CreateChannel();

// Create a new Employee.

Employee emp = new Employee()

{

DateOfBirth = DateTime.Now,

Name = "Allen Jones"

};



533



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

10-13. Create a SOAP-Based Web Service

Tải bản đầy đủ ngay(0 tr)

×