1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 142 ppsx

10 373 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 123,24 KB

Nội dung

Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1373 Chapter 29: Building and Consuming Services is WSHttpBinding_ICalculator , which is a reference to the < binding > element contained within the < wsHttpBinding > element: As demonstrated, the Visual Studio 2008 enhancements for WCF do make the consumption of these services fairly trivial. The next step is to code the consumption of the service interface to the GUI that was created as one of the first steps. Writing the Consumption Code The code to consume the interface is quite minimal. The end user places a number in each of the two text boxes provided and clicks the button to call the service to perform the designated operation on the provided numbers. Listing 29-31 is the code from the button click event: Listing 29-31: The button click e vent to call the service VB Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim ws As New ServiceReference.CalculatorClient() Dim result As Integer result = ws.Add(TextBox1.Text, TextBox2.Text) Response.Write(result.ToString()) ws.Close() End Sub C# protected void Button1_Click(object sender, EventArgs e) { ServiceReference.CalculatorClient ws = new ServiceReference.CalculatorClient(); int result = ws.Add(int.Parse(TextBox1.Text), int.Parse(TextBox2.Text)); Response.Write(result); ws.Close(); } This is quite similar to what is done when working with Web references from the XML Web services world. First is an instantiation of the proxy class, as shown with the creation of the svc object: Dim ws As New ServiceReference.CalculatorClient() Working with the ws object now, the IntelliSense options provide you with the appropriate Add() , Sub- tract() , Multiply() ,and Divide() methods. As before, the requests and responses are sent over HTTP as SOAP 1.2. This concludes the short tutorial demonstrating how to build your own WCF service using the HTTP protocol and consume this service directly into an ASP.NET application. 1373 Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1374 Chapter 29: Building and Consuming Services Working with Data Contracts Thus far, when building the WCF services, the defined data contract has relied upon simple types or primitive datatypes. In the case of the earlier WCF service, a .NET type of Integer was exposed, which in turn was mapped to an XSD type of int .Whileyoumaynotbeabletoseetheinputandoutputtypes defined in the WSDL document provided via the WCF-generated one, they are there. These types are actually exposed through an imported .xsd document ( Calculator.xsd and Calculator1.xsd ). This bit of the WSDL document is presented in Listing 29-32: Listing 29-32: Imported types in the WSDL document <wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation="http://localhost:51715/WCFService1/Calculator.svc?xsd=xsd0" namespace="http://tempuri.org/" /> <xsd:import schemaLocation="http://localhost:51715/WCFService1/Calculator.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" /> </xsd:schema> </wsdl:types> Typing in the XSD location of http://localhost:51715/WCFService1/Calculator.svc?xsd=xsd0 gives you the input and output parameters of the service. For instance, looking at the definition of the Add() method, you will see the following bit of code, as shown in Listing 29-33. Listing 29-33: Defining the required types in the XSD <xs:element name="Add"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="a" type="xs:int" /> <xs:element minOccurs="0" name="b" type="xs:int" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="AddResponse"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="AddResult" type="xs:int" /> </xs:sequence> </xs:complexType> </xs:element> This bit of XML code indicates that there are two required input parameters ( a and b )thatare of type int ; in return, the consumer gets an element called < AddResult >, which contains a value of type int . As a builder of this WCF service, you did not have to build the data contract because this service used simple types. When using complex types, you have to create a data contract in addition to your service contract. 1374 Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1375 Chapter 29: Building and Consuming Services Building a Service with a Data Contract For an example of working with data contracts, create a new WCF service (another WCF service project) called WCF_WithDataContract . In this case, you still need an interface that defines your service contract, and then another class that implements that interface. In addition to these items, you also need another class that defines t he data contract. As with the service contract, which makes use of the < ServiceContract() > and the < Operation- Contract() > attributes, the data contract uses the < DataContract() > and < DataMember() > attributes. To gain access to these attributes, you have to make a reference to the System.Runtime.Serialization namespace in your project and import this namespace into the file. Thecustomtypeinthiscaseisa Customer type, as presented in Listing 29-34. Listing 29-34: Building the Customer type VB Imports System Imports System.ServiceModel Imports System.Runtime.Serialization <DataContract()> _ Public Class Customer <DataMember()> _ Public FirstName As String <DataMember()> _ Public LastName As String End Class <ServiceContract()> _ Public Interface IHelloCustomer <OperationContract()> _ Function HelloFirstName(ByVal cust As Customer) As String <OperationContract()> _ Function HelloFullName(ByVal cust As Customer) As String End Interface C# using System.Runtime.Serialization; using System.ServiceModel; [DataContract] public class Customer { [DataMember] public string Firstname; [DataMember] public string Lastname; } Continued 1375 Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1376 Chapter 29: Building and Consuming Services [ServiceContract] IHelloCustomer public interface IWithContract { [OperationContract] string HelloFirstName(Customer cust); [OperationContract] string HelloFullName(Customer cust); } Here, you can see that the System.Runtime.Serialization namespace is also imported, and the first class in the file is the data contract of the service. This class, the Customer class, has two members: First- Name and LastName . Both of these properties are of type String . You specify a class as a data contract through the use of the <DataContract() > attribute: <DataContract()> _ Public Class Customer ‘ Code removed for clarity End Class Now, any o f the properties contained in the class are also part of the data contract through the use of the < DataMember() > attribute: <DataContract()> _ Public Class Customer <DataMember()> _ Public FirstName As String <DataMember()> _ Public LastName As String End Class Finally, the Customer object is used in the interface, as well as the class that implements the IHelloCus- tomer interface, as shown in Listing 29-35. Listing 29-35: Implementing the interface VB Public Class HelloCustomer Implements IHelloCustomer Public Function HelloFirstName(ByVal cust As Customer) As String _ Implements IHelloCustomer.HelloFirstName Return "Hello " & cust.FirstName End Function Public Function HelloFullName(ByVal cust As Customer) As String _ Implements IHelloCustomer.HelloFullName Return "Hello " & cust.FirstName & " " & cust.LastName 1376 Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1377 Chapter 29: Building and Consuming Services End Function End Class C# public class HelloCustomer: IHelloCustomer { public string HelloFirstName(Customer cust) { return "Hello " + cust.Firstname; } public string HelloFullName(Customer cust) { return "Hello " + cust.Firstname + " " + cust.Lastname; } } Building the Consumer Now that the service is running and in place, the next step is to build the consumer. To begin, build a new ASP.NET application from Visual Studio 2008 and call the project HelloWorldConsumer .Again, right-click on the solution and select Add Service Reference from the options provided in the menu. From the Add Service Reference dialog box, add the location of the WSDL file for the service and press OK. This adds the changes to the references and the web.config file just as before, enabling you to con- sume the service. The following code, as presented in Listing 29-36, shows what is required to consume the service if you are using a Button control to initiate the call. Listing 29-36: C onsuming a custom type through a WCF service VB Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim ws As New ServiceReference.HelloCustomerClient() Dim myCustomer As New ServiceReference.Customer() myCustomer.Firstname = "Bill" myCustomer.Lastname = "Evjen" Response.Write(ws.HelloFullName(myCustomer)) ws.Close() End Sub C# protected void Button1_Click(object sender, EventArgs e) { ServiceReference.HelloCustomerClient ws = new ServiceReference.HelloCustomerClient(); ServiceReference.Customer myCustomer = new ServiceReference.Customer(); Continued 1377 Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1378 Chapter 29: Building and Consuming Services myCustomer.Firstname = "Bill"; myCustomer.Lastname = "Evjen"; Response.Write(ws.HelloFullName(myCustomer)); ws.Close(); } As a consumer, once you make the reference, you will notice that the service reference provides both a HelloCustomerClient object andthe Customer object, which was defined through the service’s data contract. Therefore, the preceding code block just instantiates both of these objects and builds the Customer object before it is passed into the HelloFullName() method provided by the service. Looking at WSDL and the Schema for HelloCustomerService When you make a reference to the HelloCustomer service, you will find the following XSD imports in the WSDL: <wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation="http://localhost:51715/WCFService1/HelloCustomer.svc?xsd=xsd0" namespace="http://tempuri.org/" /> <xsd:import schemaLocation="http://localhost:51715/WCFService1/HelloCustomer.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" /> <xsd:import schemaLocation="http://localhost:51715/WCFService1/HelloCustomer.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/" /> </xsd:schema> </wsdl:types> http://localhost:51715/WCFService1/HelloCustomer.svc?xsd=xsd2 provides the details on your Customer object. The code from this file is shown here: <?xml version="1.0" encoding="utf-8" ?> <xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/"> <xs:complexType name="Customer"> <xs:sequence> <xs:element minOccurs="0" name="Firstname" nillable="true" type="xs:string" /> <xs:element minOccurs="0" name="Lastname" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:element name="Customer" nillable="true" type="tns:Customer" /> </xs:schema> 1378 Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1379 Chapter 29: Building and Consuming Services This is an XSD description of the Customer object. Making a reference to the WSDL includes the XSD description of the Customer object and gives you the ability to create local instances of this object. Using this model, you can easily build your services with your own defined types. Namespaces Note that the services built in the chapter have no defined namespaces. If you looked at the WSDL files that were produced, you would see that the namespace provided is http://tempuri.org . Obviously, you do not want to go live with this default namespace. Instead, you need to define your own namespace. To accomplish this task, the interface’s < ServiceContract() > attribute enables you to set the names- pace, as shown here: <ServiceContract(Namespace:="http://www.lipperweb.com/ns/")> _ Public Interface IHelloCustomer <OperationContract()> _ Function HelloFirstName(ByVal cust As Customer) As String <OperationContract()> _ Function HelloFullName(ByVal cust As Customer) As String End Interface Here, the < ServiceContract() > attribute uses the Namespace property to provide a namespace. Summary This chapter was a whirlwind tour of XML Web services in the .NET platform. It is definitely a topic that merits an entire book of its own. The chapter showed you the power of exposing your data and logic as SOAP and also how to consume these SOAP messages directly in the ASP.NET applications you build. In addition to pointing out the power you have for building and consuming basic Web services, the chapter spent some time helping you understand caching, performance, the use of SOAP headers, and more. A lot of power is built into this model; every day the Web services model is starting to make stronger inroads into various enterprise organizations. It is becoming more likely that to get at some data or logic you need for your application, you will employ the tactics presented here. This chapter also looked at one of the newest capabilities provided to the .NET Framework world. The .NET Framework 3.5 and WCF are a great combination for building advanced services that take ASP.NET Web services, .NET Remoting, Enterprise Services, and MSMQ to the next level. While not e xhaustive, this chapter broadly outlined the basics of the framework. As you start to dig deeper in the technology, you will find capabilities that are strong and extensible. 1379 Evjen c30.tex V2 - 01/28/2008 3:57pm Page 1381 Localization Developers usually build Web applications in their native language and then, as the audience for the application expands, they then realize the need to globalize the application. Of course, the ideal is to build the Web application to handle an international audience right from the start — but, in many cases, this may not be possible because of the extra work it requires. It is good to note that with the ASP.NET 3.5 framework, a considerable effort has been made to address the internationalization of Web applications. You quickly realize that changes to the API, the addition of capabilities to the server controls, and even Visual Studio itself equip you to do the extra work required more easily to bring your application to an international audience. This chapter looks at some of the important items to consider when building your Web applications for the world. Cultures and Regions The ASP.NET page that is pulled up in an end user’s browser runs under a specific culture and region setting. When building an ASP.NET application or page, the defined culture in which it runs is dependent upon both a culture and region setting coming from the server in which the application is run or from a setting applied by the client (the end user). By default, ASP.NET runs under a culture setting defined by the server. The world is made up of a multitude of cultures, each of which has a language and a set of defined ways in which it views and consumes numbers, uses currencies, sorts alphabetically, and so on. The .NET Framework defines cultures and regions using the Request for Comments 1766 standard definition (tags for identification of languages) that specifies a language and region using two-letter codes separated by a dash. The following table provides examples of some culture definitions. Evjen c30.tex V2 - 01/28/2008 3:57pm Page 1382 Chapter 30: Localization Culture Code Description en-US English language; United States en-GB English language; United Kingdom (Great Britain) en-AU English language; Australia en-CA English language; Canada Looking at the examples in this table, you can see that four distinct cultures are defined. These four cultures have some similarities and some differences. All four cultures speak the same language (English). For this reason, the language code of en is used in each culture setting. After the language setting comes the region setting. Even though these cultures speak the same language, it is important to distinguish them further by setting their region (such as US for the United States, GB for the United Kingdom, AU for Australia, and CA for Canada). As you are probably well aware, the English language in the United States is slightly different from the English language that is used in the United Kingdom, and so forth. Beyond language, differences exist in how dates and numerical values are represented. This is why a culture’s language and region are presented together. The differences do not break down by the country only. Many times, countries contain more than a single language and each area has its own preference for notation of dates and other items. For example, en-CA specifies English speakers in Canada. Because Canada is not only an English-speaking country, it also includes the culture setting of fr-CA for French-speaking Canadians. Understanding Culture Types The culture definition you have just seen is called a specific culture definition. This definition is as detailed as you can possibly get — defining both the language and the region. The other type of culture definition is a neutral culture definition. Each specific culture has a specified neutral culture that it is associated with. For instance, the English language cultures shown in the previous table are separate, but they also all belong to one neutral culture EN (English). The diagram presented in Figure 30-1 displays how these culture types relate to one another. From this diagram, you can see that many specific cultures belong to a neutral culture. Higher in the hierarchy than the neutral culture is an invariant culture, which is an agnostic culture setting that should be utilized when passing items (such as dates and numbers) around a network. When performing these kinds of operations, make your back-end data flows devoid of user-specific culture settings. Instead, apply these settings in the business and presentation layers of your applications. Also, pay attention to the neutral culture when working with your applications. Invariably, you are going to build applications with views that are more dependent on a neutral culture rather than on a specific culture. For instance, if you have a Spanish version of your application, you probably make this version available to all Spanish speakers regardless of their regions. In many applications, it will not matter if the Spanish speaker is from Spain, Mexico, or Argentina. In a case where it does make a difference, use the specific culture settings. 1382 Evjen c30.tex V2 - 01/28/2008 3:57pm Page 1383 Chapter 30: Localization Invariant Culture EN (Neutral Culture) en-US en-GB en-AU en-CA es -ES es -MX es -AR ES (Neutral Culture) Figure 30-1 The ASP.NET Threads When the end user requests an ASP.NET page, this Web page is executed on a thread from the thread pool. The thread has a culture associated with it. You can get information about the culture of the thread programmatically and then check for particular details about that culture. This is illustrated in Listing 30-1. Listing 30-1: Checking the culture of the ASP.NET thread VB Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim ci As CultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture Response.Write("<b><u>CURRENT CULTURE’S INFO</u></b>") Response.Write("<p><b>Culture’s Name:</b> " & ci.Name.ToString() & "<br>") Continued 1383 . 01/28/2008 3: 53 pm Page 137 3 Chapter 29: Building and Consuming Services is WSHttpBinding_ICalculator , which is a reference to the < binding > element contained within the < wsHttpBinding >. tutorial demonstrating how to build your own WCF service using the HTTP protocol and consume this service directly into an ASP. NET application. 137 3 Evjen c29.tex V2 - 01/28/2008 3: 53 pm Page 137 4 Chapter. service. For instance, looking at the definition of the Add() method, you will see the following bit of code, as shown in Listing 29 -33 . Listing 29 -33 : Defining the required types in the XSD <xs:element

Ngày đăng: 05/07/2014, 19:20