Creating Web Service Data Sources


When the .NET Framework was first announced in 1999 and finally released in 2002, Microsoft made everyone believe that .NET was all about XML Web Services. It wasn't, and it still isn't. Because of this focus on Web Services, some developers working with traditional client/server or simple disconnected architectures were dissuaded from adopting the .NET Framework. Frankly, I think this is probably good. Because of .NET's low adoption rate, Microsoft has had the time to refine the .NET Framework and build up support for other architectures like Windows Forms (now dubbed "Smart Client"), Business Objects, and ASP.NET.

Today, Microsoft is still talking about Service Oriented Architectures (SOA), and Web Services is only a part of that approach to application design. Given the number of questions ordinary developers are asking about Web Services, I can only surmise that Web Services is playing no greater role than DCOM did before the .NET Framework. Because of this, I'm not going to focus heavily on Web Services (or Business Objects) here. I do want to outline the steps through the process of attaching a Web Service to a Data Source so that you don't have to face the frustration I did when trying this.

The DSCW can build a TableAdapter from a Web Service if the Web Service exposes a strongly typed data structure. No, the Data Source window does not simply expose the Web Services method(s), but the elements of the Web Service that return data. You'll also discover that the DSCW does very little for you beyond exposing these data elements. The Data Source designer is not implemented when working with Web Services, nor does it generate the code needed to call the Web Service method to return the data.

What Is a Web Service?

A Web Service is a block of code that looks alarmingly like an ASP.NET page that has no user interfacethat's because it is. Some feel that Web Services are designed to replace remote COM objects that run on a server somewhere on the LANwhat I call "distributed" COM objects or DCOM. Web Services have been used to implement SQL Server Reporting Services, SharePoint Services, Amazon.com e-commerce web services[6], and other sophisticated service engines. It's clear that one can use Web Services for some pretty serious and sophisticated applications.

[6] See www.amazon.com/gp/browse.html/104-8293193-5423957?%5Fencoding=UTF8&node=3435361.

IMHO

The fact that Web Services can expose objects, methods, and (most importantly) structured information over the Web makes Web Services very attractive to architects and developers wishing to increase the breadth of their applications.


When working with any object that runs in another memory space on another processor (like Web Services), you have to think about each operation the object is to perform in a number of different ways:

  • The object must be managed independently from the applications that make use of it. In the case of Web Service objects, it means that the IIS server that's hosting the Web Service is responsible for managing (and restricting) access to the servicejust as it would for any other ASP executable. IIS launches instances of the Web Service on demand and manages a pool of running (and waiting) instances. IIS prevents access by unauthorized users but permits administrators to fine-tune those restrictions.

  • The object must be visible to the LAN or the Web. That is, once you know where to look, you have to determine whether the object is present, accessible, and running. In the case of Web Services, you can query the target server (if you know its address) or depend on a "UDDI" server to expose registered Web Services to those who go trolling for services.

  • The object structure must be "discoverable." This means an application must be able to determine what the object "looks like" in its current state. For example, the tools and your application have to be able to determine what entry points the Web Service exposes (methods), what arguments are to be applied to those methods, and (most importantly for Data Sources) what data structure is returned. Since remote code can and does evolve over time, there must be a mechanism to ensure that the application is made aware that the signature of the object has changed.

  • The security context in which a Web Service executes is (usually) independent of the "user" running the application. As with ASP applications, managing security and data connections for Web Services can be fairly complex. Typically, an ASP application runs either under the ASPNET account or under a specially configured SQL Server Login account that is granted specific (limited) rights. Web Services are no different in this respect.

  • Web Services are different from ASP applications, in that they are designed to be controlled by and extrude XML result sets. To standardize (and popularize) Web Services, the Simple Object Access Protocol (SOAP) was developed and handed over to the XML Protocol Working Group of the World Wide Web Consortium. This means developers (usually via tools like Visual Studio) interact with Web Services via SOAP.

It's really beyond the scope of this book to try to teach you how to build and manage a professional Web Service or how to access remote objects using the SOAP protocol. However, I do know there are a number of data sources out there that are exposed as XML Web Services, and I do want to help you gain access to this data. Consider that the ReportViewer control can also be used to expose data from a Web Service. This makes it doubly important to make sure you understand how to leverage them and how to help others that do build Web Services for you understand how they must be configured so that your applications can access them.

Constructing a Sample Web Service

At this point, I want to walk you through the process of building a Web Service that returns data capable of being exposed by a Data Source, so I can use it as an example. No, not all Web Service data structures can be "seen" by the Visual Studio Data Source Configuration wizard (DSCW)only those that return strongly typed DataTable or DataSet objects. Remember, when the DSCW runs, it creates a strongly typed TableAdapter. In order for your Web Service to be visible to the DSCW, you'll have to return a strongly typed TableAdapter one way or another.

IMHO

The process I'm about to go through is made more difficult by the lack of tools on the ASP.NET side of Visual Studio.


1.

Start Visual Studio 2005 and click on "File | New Web Site...". No, I'm not really going to create a web site in the traditional sense, but remember that a Web Service is managed by IIS (or the local IIS host).

2.

Choose "ASP.NET Web Service" from the list of new web site templates.

3.

Name the web site so it's easy to find (and does not collide with another site). I chose to create the new Web Service on the local IIS system, but the template wizard can build the site on the file system, an FTP site, or a selected remote site. Click "Browse" to display a dialog to help locate the site (as shown in Figure 6.45).

Figure 6.45. Choosing the local IIS "location" for the Web Service.


If you build the Web Service on the file system, you'll have trouble testing it later.


4.

Click "Open" to generate the code for the Web Service "site." This also generates the required template Service class and a sample "Hello World" method, as shown in Figure 6.46.

Figure 6.46. The generated Web Service and sample method.


5.

It's useful to debug this sample code. It triggers a few hints and makes a few changes that enable debugging (by changing the web.config file). Let's walk through that process. Press F5 to start debugging or press the green start debug arrow.

When you develop a Web Service on the local IIS server, the program files are persisted (by default) in the IIS directory, so you might want to back up this directory when you do source-control management.


6.

At this point, a dialog appears that informs you that you can't debug without changing the web.config fileit automatically changes it if you press OK.

7.

The next dialog (see Figure 6.47) is an instance of Internet Explorer (IE) that exposes the service. Note that the "IIS" server in this case is implemented via port 2300. It also includes a link to run the Web Service method. More importantly, the page includes a warning to remind you to set the Web Service decoration to address the correct namespace.

Figure 6.47. Internet Explorer shows this page when navigating to the Web Service.


Farther down on this page, you'll find code examples for C#, Visual Basic .NET, and C++ to modify the Web Service decoration (as shown in Figure 6.48). These are examples of how to change the namespace used by the Web Service to be unique.

Figure 6.48. Examples of providing a unique Web Service namespace.


8.

If you want to, click on the "Hello World" link. This launches another page (see Figure 6.49) designed to execute the code in the Web Service and return an XML rendition of the results. This page also contains the coded SOAP request and response to help you write a direct SOAP invocation of the Web Servicefortunately, you won't have to go to that trouble, as Visual Studio is going to do that for us behind the scenes.



Figure 6.49. The auto-generated web page used to invoke the Web Service method.


Clicking "Invoke" returns XML that represents the data returned from the Web Service (as shown in Figure 6.50).

Figure 6.50. The XML returned by the "Hello World" Web Service.


I'm ready to return back to our project and make some changes to the Web Service class decorations and implement a real method.

9.

Close the IE windows. This should return you to Visual Studio and the App_Code/Service.xx code block.

At this point, alter the Web Service decoration to point to the path or the HTML location of your file-based web service. I also don't want to name our Web Service "service", so I need to change the name in a number of places:

1.

First, change the name of the Public Class Service. I'm naming the Web Service AuthorsWebService. Note that Visual Studio helps in this renaming process (to a very limited extent, in this case), as shown in Figure 6.51.

Figure 6.51. Renaming the Namespace and Web Service class.


2.

Next, change the name of the Service.aspx in the Solution Explorer to AuthorsWebService.aspx. I also changed the name of the Service.VB file to AWService.vb, and changed the AuthorsWebService.asmx file to reflect these changes, as shown in Figure 6.52.

Figure 6.52. Renaming the Web Service support files to AuthorsWebService.


3.

It would be a good idea to retest the Web Service (click the debug button) to ensure that these changes were made correctly.

IMHO

It's a shame that the Visual Studio Web Service template wizard did not give us an opportunity to properly name the service.

4.

I'm ready to add a strongly typed DataSet to the project. Remember that a Web Service can return only a strongly typed data structure.

Note that you won't find the Data Source Configuration wizard here, so you'll have to use one of the older "tried and true" methods to get the code generated or simply import the XSD file from a Windows Forms project.


5.

To build our strongly typed DataSet as I discussed earlier in the chapter, right-click on the project App_Code folder and select "Add New Item". This adds the code to generate a strongly typed DataSet to the project. I named this new DataSet AuthorsData. Click Next to launch the (now familiar) TableAdapter Configuration wizard.

6.

Step through the TACW to create a TableAdapter against the data you wish the Web Service to return. In this case, I execute the AuthorsByYearBorn stored procedure for our example Web Service and choose the GetData method to expose the data. The TACW creates an AuthorsByYearBorn.xsd file in the App_Code folder in our project.

7.

In the project, I need to instantiate and reference the strongly typed data class, so I add code to declare two new objects:

  • A strongly typed TableAdapter to expose the GetData method

  • A strongly typed DataTable to serve as a transport mechanism for the data returned from the Web Service

The code to implement these operations is shown in Figure 6.53.

Figure 6.53. Implementing the Web Service method to return a strongly typed DataTable.


Note that I added the new method AuthorsByYearBorn (with the decoration of <WebMethod()>. This means our Web Service exposes two methods, but only one returns a strongly typed data structure.

The code also includes a subroutine to validate the input parameters to ensure that their range is correct. This is an example of a business rule of sorts. This Validate routine is shown in Figure 6.54.



Figure 6.54. Validating the input parameters in a business rule.


8.

The new Web Service is now ready to test. Press F5 or the debug button to start the test. IE now exposes the AuthorsWebService and the single method I implemented as shown in Figure 6.55.

Figure 6.55. IE exposes both methods of our Web Service.


Tip

If you get an exception that complains that you don't have permission to view the page, make sure that the .ASPX page is set as the start page.

9.

Click on the circled "AuthorsByYearBorn" link in IE to launch the Web Service test application. Enter values for the two input parameters as circled in Figure 6.56, and click Invoke to execute the Web Service code that retrieves the data.

Figure 6.56. Enter the input parameters into the IE test page.


To debug the Web Service code, simply set a breakpoint on any line of code in the Web Service language file (AWService.VB, in this example). When IE launches the Web Service, Visual Studio breaks at that line (if the logic reaches it).

At this point, IE displays the XML returned by the Web Service. It includes both the strongly typed schema and data from the query, as shown in Figure 6.57.

Now that your Web Service is tested, you're ready to access and test it from a "consumer" application.

Figure 6.57. The XML data returned by the Web Service.


Consuming and Testing Web Services

I'm ready to use the Data Source Configuration wizard to locate, link to, and test our new Web Service. I usually start a new instance of Visual Studio to consume remote objectsit just makes managing the two projects simpler.

1.

Create a new Visual Studio Windows Forms project. I called ours ConsumeTestWebService.

2.

Create a new Data Source for the project by launching the DACW. Click on "Web Service" when asked to choose a Data Source Type. Click Next and you should see the "Start Browsing for Web Services" dialog, as shown in Figure 6.58.

Figure 6.58. Browsing for Web Services.


3.

Click on "Web services on the local machine". Yes, you can enter the URL for the target Web Service if you know it, or ask Visual Studio to search for UDDI Servers (Web Service publishers) on the local network. This should expose not only the Web Service I just created (AuthorsWebService), but others created by members of our development team and those exposed by other Web Service providers. In this case (as shown in Figure 6.59), I can see Web Services exposed by Reporting Services 2000 and 2005.

Figure 6.59. The Web Service browser found these Web Services on the local system.


4.

Click on the "AuthorsWebService" link to set the "Add Web Reference" dialog URL to point to our IIS server's AuthorsWebService.ASMX file and expose both of the Web Service's methods (as shown in Figure 6.60).



Figure 6.60. Choosing a specific Web Service exposes the methods it implements.


5.

If you click on either method, you're taken back to the test routine you saw when you were developing the Web Service. Instead, click on the "Add Reference" button and "Finish" on the next dialog to confirm the Web reference URL I want to pass to our project and Data Source.

When the DSCW closes, the Visual Studio has generated no XSD file. Note that the second method exposed (HelloWorld) is not exposed in the Data Sources window at allit does not return a strongly typed data structure. But I'm not done yet. Visual Studio won't generate the XSD file or other important Web Service .disco and .wsdl files until you build the project.

6.

Right-click on the Project Explorer and choose "Build Project". This adds a number of files to the project as Visual Studio generates the TableAdapter for our Web Service Data Source. The final result is shown in Figure 6.61.

Figure 6.61. The Web Service "Data Source" and the post-build generated files.


I'm not sure you could really call this a "Data Source," as most of the functionality is not implemented for Web Services, but consider that the data definition is not here in this application as it is for the other Data Sources I've created so farit's in the Web Service. At this point, I'm permitted to consume the Web Service but not alter it or the data structures it returns. I can't add to or change the methods or their signatures, either.

Exposing the Web Service Data Source in the UI

Yes, you can drag and drop the Web Servicegenerated DataTable to the Form, and, yes, Visual Studio generates some of the same UI elements it created for a "Database" Data Sourcebut not all, and it does not add any code to Form_Load. The code is all up to you.

Dragging the AuthorsByYearBorn DataTable from the Data Source Designer to the Form generates (as shown in Figure 6.62):

  • AuthorsData: A strongly typed DataSet.

  • AuthorsByYearBornBindingSource: A BindingSource control to interface the data source and the bound control.

  • AuthorsByYearBornBindingNavigator: A UI element to navigate from row to row in the bound BindingSource data source.

  • A DataGridView control to display the data. This control is populated with the column names from the strongly typed DataSet.

Figure 6.62. Dragging the Web Service DataTable to a Windows Form.


Unlike a "database" Data Source, when working with a Web Service Data Source, you'll have to add code (by hand) to call the Web Service method(s) to populate the strongly typed DataTable. In this case, this means you'll have to supply two input parameters and code your own parameter-collection code to capture and validate them. You'll also have to code your own "Fill" button to execute the method code. It would be nice if Microsoft had included the "ToolStrip" button to manage these UI elements as it did for database Data Sources.

In about 5 minutes, I was able to create my own ToolStrip to handle each of the parameters and expose a button to launch the Fill (as shown in Figure 6.63).

Figure 6.63. The customized ToolStrip control.


The code to fetch the data is not all that complicatedonce you figure out where it's coming from. That part is not at all intuitive until you've created dozen of these applications. The surprising part is that the Web Service is exposed off the Form's (My) WebServices. The AuthorsWebService exposes each method (even HelloWorld). Intellisense helps you figure out how to build and reference the other objects that are passed and returned. Note that the input parameters are drawn from the ToolStrip TextBox controls. Since the strongly typed DataTable inherits from System.Data.DataTable, it's possible to bind to its DefaultView and sort the rowset before showing it to the user.

Figure 6.64. The code used to fetch execute the WebService method.


I hope this chapter gives you a better understanding of the Data Source paradigm. I also hope you have enough information to help decide where this approach makes sense and where it doesn't.




Hitchhiker's Guide to Visual Studio and SQL Server(c) Best Practice Architectures and Examples
Hitchhikers Guide to Visual Studio and SQL Server: Best Practice Architectures and Examples, 7th Edition (Microsoft Windows Server System Series)
ISBN: 0321243625
EAN: 2147483647
Year: 2006
Pages: 227

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net