现在的位置: 首页 > 综合 > 正文

20100525 学习记录:关于发布网站嵌套的bin文件夹 和 Could not create type….报错 = =+

2012年08月13日 ⁄ 综合 ⁄ 共 38359字 ⁄ 字号 评论关闭
文章目录

这还是上周的事情了,现在才总结。我的标题取的名字似乎也不准确 - =

 

事情缘由是我需要在我们网站下的根目录里放一个新的文件夹里面装webservice,并且这个webservice要用url可以独立访问(废话 - =)

结果我本地调试成功后放到服务器上部署时就是死活不好用,报错:

Could not create type 'Service'.

<%@ WebService Language="C#" CodeBehind="~/App_Code/Service.cs" class="Service" %>

......

 我检查了n遍确认我的codebehind木有写错,class也木有写错,因为我右键页面的.asmx文件→view code也能顺利的找到对应的.cs文件,所以应该不是这里找不到才对。但是手头上有一个好用但是代码超级简单的ws的例子放在服务器上就可以用 = =+ 我比对2者的区别之后,再加上搜索得来的信息判断错误就是页面找不到我的.cs文件导致的,因为我的程序跟他们最大的区别就是他们把代码直接写在.asmx文件中了 - = ......

可是我的指向明明也没有错,那是为什么呢?

 

先来总结一下,网络上搜索得来的关于这个报错的解决办法吧~ =v=

话说有这个错误的人真是不在少数,少部分幸运找到根源的都是一些低级错误(你以为你错误高级.... - =):

1.  页面里的class值不对,应该注意加上命名空间的名字

eg: 如果我的Service.cs文件里有个明明空间叫WS,那么class里面就应该写为WS.Service,嗯

2. codebehind就不用说了吧.... 其实这个一般都是默认生成的...

3. 又是万恶的IIS!!记得一定要用2.0发布,选1.0的8行!在IIS的asp.net页签里面设置

4. 发布文件夹在IIS中必须create成application,不然看不到

5. 居然也有在IIS中的Edit Configuration里,把Authentication改成none好用的.... 8理解....

6. 哦,对了,还有,这个webservice有专门new webservice project的选项... 切记...

7. 还有一个properties的设置。这个我的VS版本里没有这个功能,所以没法尝试,下面会给出具体说明,偶就不详细说了

8.........当然,上面这么多种方法仍然解决不了很多人的问题包括我 = = ,很多人最后放弃ws了 orz,但偶发挥小强精神最后终于找到了根源(少废话!((‵□′)) )

好吧,先给出第7条的详细解释,然后再解释我的.... =。=

 

 

How do I – Solve the “Could not create type WebService.Name” error when trying to deploying a web service?

OK, so you wrote a web service and you may even have tested it and everything worked fine. So the you did some "cleanup" and tried to deploy the web service. It compiles and deploys just fine, but when you try to invoke and hit the service you are presented with the following error:

Server Error in '/' Application.

Parser Error

Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: Could not create type 'WebServices.Candidates'.

Source Error:

 

Line 1: <%@ WebService Language="C#" CodeBehind="Candidates.asmx.cs" Class="WebServices.Candidates" %>


Source File: /Candidates.asmx    Line: 1

 

So just how do you solve this problem?

Here's my checklist of things to check when having trouble deploying web services:

  1. Check that IIS is using ASP.NET 2.0.
    1. Begin by starting up the Internet Information Services manager.
    2. Expand "Web Sites".
    3. Expand your web site e.g. "Default Web Site".
    4. Locate the Virtual Directory to which the web service was deployed and right click it.

    1. On the popup menu, click "Properties".
    2. On the Properties window, select the "ASP.NET" tab.
    3. Ensure that the APS.NET Version is set to 2.0.x and not 1.1.x.
    4. If it is set to 1.1.x, set it to 2.0.x and retry your web service.
  2. Ensure your Visual Studio build properties are set correctly.
    1. Locate the .asmx file in your Solution Explorer pane and right click it.

    1. On the popup menu, click "Properties".
    2. Ensure that the Build Action is set to "Content".

    1. Locate the code behind (.cs or .vb) file in the Solution Explorer and right click it.

    1. On the popup menu, click "Properties".
    2. Ensure the Build Action is set to "Compile".

    1. If either of these weren't set correctly, make the correction, recompile, redeploy and retest.
  3. Ensure ASP.NET 2.0 is an Allowed web services extension.
    1. Open the IIS Manager.
    2. Expand your computer.
    3. Click the "Web Service Extensions" option.
    4. In the right hand pane, locate the "ASP.NET v2.0.x" entry and ensure that its Status is "Allowed". If it is not allowed, the "Allow" button on the left will be enabled. Click it to change the setting.

    5. If it was not allowed, correct the setting and retry your service.
  4. Check for the WebMethod attribute.
    1. Review your code and ensure that you have the [WebMethod] attribute set for all web methods in the service. This does not mean that all methods have to be web methods, but the ones you are trying to consume should have this attribute in its declaration.

  5. Ensure the .asmx and code behind file match definitions.
    1. Open your code behind (.cs or .vb) file.
    2. Look at the web service declaration at the top.

    1. In our example, ensure that #2 and #3 match. If they don't, correct the problem.
    2. Next note the namespace at #1.
    3. Now open the .asmx file. This can usually be done by double clicking it in the Solution Explorer, but if you're not able to get it to open through the IDE, open Windows Explorer, navigate to the file, right click it and select Open in Visual Studio to work around the problem.
    4. Now look at the code.

    1. Note the value of Class in this case is "WebServices.Candidates". The Class value should be the full namespace value as well as the class name. Given our code behind file's values, in this case, the Class value should have been "Crowe.PartnerNomination.WebServices.Candidates", but instead it is just "WebServices.Candidates". This is a common issue when reworking already written web services into a namespace hierarchy. For some reason the .asmx file does not always reflect the changes made which then causes the error message at the beginning of this post.
    2. Change the Class value, recompile, redeploy and retest.

Later
C

 From:http://www.cjvandyk.com/blog/Lists/Posts/Post.aspx?ID=133

 

这位狠人总结的相当全面了,赞!!!但是仍然解决不了我的。。。 = =

于是不废话了,偶当时受这本书启发《Programming .NET Web Services》 封面上一只奇怪的鸟... 这本书太赞了!!!!!!!!!搞的我都想买了 - =

是里面的一段话提示了我:

 

The \bin directory is the first place that .NET looks for compiled assemblies, and so every ASP.NET web service should have a \bin directory located directly beneath the application root folder. If one is not automatically created for you by a tool like VS.NET, you can create one manually by using Windows Explorer to navigate to the application's root folder (called DNSService in the previous example) and creating a new folder called root.

Remember that the location of the \bin directory is always relative to the virtual application root. Because IIS allows you to have nested virtual applications, sometime figuring out which \bin directory goes with which application can be confusing.

 

 

于是偶瞬间想通,不就是差这个问题么,是页面找不到bin文件夹里的dll的原因!!!!!

为啥找不到?因为根目录下已经有一个bin文件夹了,我的ws默认去找了根目录的bin文件夹,结果当然找不到它要的dll.

其实如果没有重名的话,把bin目录合并就可以了,可是因为ws生成的dll是App_Code.dll ,根目录已经有一个重名的了,所以偶不能凑合把ws的扔到根目录。于是我剩下两条路:

1. 把ws的代码放入根目录的程序一起作为一个工程编译——根目录主要是asp开发的,有少量.net重写代码。不想把ws跟网站混在一起,此路不通

2.继续研究为啥页面不找自己的bin而找根目录。。。 (┬_┬)

 

还是这本英明无比的书,下面紧接着又写——

For example, consider Figure 2-14, and let's assume a code-behind .asmx page resides in the folder named dir2. If the virtual directory named store is configured as a virtual application, then .NET will attempt to find the associated code-behind assembly in the \bin directory associated with the store virtual application (www.yyz.com\store\bin). If, however, the store virtual directory is not configured as a virtual application, .NET will look in the \bin directory located at www.yyz.com\bin.

.NET always looks for the \bin directory located directly underneath the application root. If you start seeing .NET error messages like "Could not create type `xxx'", it's probably due to a problem with the way you've configured your virtual application.

Figure 2-14. \bin directory locations

 

 

 

 默认是找自己的目录,找不到才找根目录的,可我的正相反,不找自己的找根目录的,而且我的ws目录也发布成application了。。。

在博问上提了问题,大家给出的建议:

1. 合并工程...

2. 作为作为一个application  相当于一个子站点发布?

3.单独发布网站,绑定一个子域名————完全没理解这位仁兄的意思 = =||||

 

可能是我没理解他们的意思,但是觉得虽然上面说的貌似不全中,但是指点了我,最后偶发现指定虚拟路径就可以了。不过我只是给ws文件夹了一个名字(大概就是所谓的子域名吧!)并没有作为网站发布,还是原来发布为application的状态(区别到底是什么 = =+)

这样,我的ws就能成功的找到自己文件夹下的bin了.....

 

唉,我想网上跟我犯同样错误的人一定n多..............

最后,列一下偶搜索的无数链接中有点用的几个链接,严重感谢《Programming .NET Web Services》!!!

 

http://www.cjvandyk.com/blog/Lists/Posts/Post.aspx?ID=133

http://social.msdn.microsoft.com/Forums/zh-TW/asmxandxml/thread/838706ac-6763-455b-95bd-1432a9ccc6be 

http://forums.asp.net/p/1328663/2659836.aspx

http://oreilly.com/catalog/prognetws/chapter/ch02.html (http://oreilly.com/catalog/prognetws/chapter/ch02.html#77068)

 

提的2个问题,非常感谢回答问题的大家 (┬_┬)

http://space.cnblogs.com/question/14455/

http://space.cnblogs.com/question/14467/ 


Search the Catalog
Programming .NET Web Services

Programming .NET Web Services

By Alex Ferrara, Matthew MacDonald
September 2002
0-596-00250-5, Order Number: 2505
414 pages, $39.95 US $61.95 CA

Chapter 2
Creating ASP.NET Web Services

Using the .NET Framework, it's easy to get a basic service up and running. In just a few minutes and fewer lines of code, you can put together a simple "Hello World" service without any understanding of HTTP, SOAP, WSDL or any of the several technologies that form the basis for web services. In fact, if you're a Microsoft Visual Studio .NET user, all you need to do to create a simple "Hello, World" service is to open a new Visual C# or Visual Basic ASP.NET Web Service project and uncomment the sample code provided by the template.

In this chapter, you'll learn about ASP.NET, the new Microsoft technology for building web applications and services, and how to use the .NET platform and Visual Studio .NET to create some simple web services. We'll also talk about some of the features of .NET that will get you on the road to developing well-documented scalable web service applications. By the end of this chapter, you'll have a solid understanding of how .NET supports web services and how to use the .NET platform to create them. We'll start with the ubiquitous "Hello, World" example exposed as a web service.

Creating a Web Service: "Hello, World"

In this section, you'll create a simple web service in the "Hello, World" tradition. Through this brief example, you'll see how easy it is to use ASP.NET to create a working web service (with a text editor or with VS.NET) and learn about the basic technologies behind .NET web service.

Creating a Web Service with Inline Code

While Visual Studio .NET provides a feature-rich integrated development environment for .NET development, it's not required to create .NET web services. Applications can also be created using your favorite text editor and the command-line tools that ship with the .NET Framework SDK. Here, we use Notepad as a text editor, but you should feel free to use whatever editor you're most comfortable with (Emacs or vi).

If you chose to develop with a text editor, you must place all of your code in one or more text files, assign them each the file extension .asmx and place them in an IIS folder on a server or workstation that has the .NET Framework installed. Once you save the code to a folder served by the IIS web server, it's ready to run--that's it! How you get the file to your web server is your business. If you're running IIS locally on your workstation (and you've installed the .NET Framework), this is as simple as saving the file to a suitable location on your local drive (e.g., c:\inetpub\wwwroot\). If you're using a remote server (in which case there's no need to have the .NET Framework installed locally), you might have to use FTP or a network share instead (more about this later).

Once you've chosen a text editor and file location, all that's left is to write the code.

Example 2-1 lists the code for a C# version of the ubiquitous "Hello, World" application; unlike the classic desktop version, this one delivers its familiar message over the Web through an exposed method called HelloWorld(). To identify the class and method as a web service to the compiler, this code uses some special notation. It also includes an ASP.NET directive at the head of the file.

To create a C# version of the HelloWorld web service, enter the code from Example 2-1 exactly as it appears, and save the file to your web server under the c:\inetpub\wwwroot folder (or whatever folder is the web root folder for your system) with the name HelloWorld.asmx.

Example 2-1. HelloWorld: C# web service

<%@ WebService Language="C#"
Class="ProgWS.Ch02.HelloWorldService" %>
using System.Web.Services;
namespace ProgWS.Ch02
{
public class HelloWorldService: WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
}

In the following sections, we'll explain the standard elements of this web service source file and then show you how to test it.

The WebService directive

Example 2-1 begins with a WebService directive, an ASP.NET statement declaring that the code that follows is a web service:

<%@ WebService Language="C#" Class="ProgWS.Ch02.HelloWorldService" %>

TIP: The WebService directive is similar to the Page directive that begins most .aspx pages.

For the HelloWorld web service to work, you must assign values to two WebService directive attributes: Language and Class.

The required Language attribute lets .NET know which programming language the class has been written in. As you might guess, the acceptable values for the language attribute are currently C#, VB, and JS for JScript.NET.

The Class attribute, also required, tells ASP.NET the name of the class to expose as a web service. Because a web service application can comprise multiple classes, some of which may not be web services, you must tell .NET which class to expose, a step analogous to declaring a Main() method to indicate the entry point of a .NET console application or component. Note that even if your web service contains only one class, setting this attribute is required.

The using directive: importing .NET namespaces

The next line in the example is a using statement that tells the compiler to alias the System.Web.Services namespace to the local namespace. For C#, this directive is:

using System.Web.Services;

This directive allows you to refer to objects in the System.Web.Services namespace without having to fully qualify the request. This statement is optional, but if it is not included, every reference to an object in this namespace must be fully qualified. An example is the next line, which is our class declaration. With the using statement, it looks as follows in C#:

using System.Web.Services;
public class HelloWorldService: WebService

Without the using statement, it would have to be written fully qualified:

public class HelloWorldService: System.Web.Services.WebService

Note: Importing a namespace does not give you access to any of the additional namespaces that appear to be nested in that namespace. In other words, if you were to import the System.Web namespace, you would not be able to refer to the System.Web.Services.WebService class as Services.WebService. While a namespace like System.Web.Services may "appear" to be nested in the System.Web namespace, that is not the case. They are implemented as two different assemblies that bear little relation to each other aside from a partial name sharing. The apparently hierarchical nature of the .NET Framework's namespaces exists in name only as an organizational convenience and has no bearing on class structure.

The namespace keyword

.NET allows you--and Microsoft encourages you--to put the classes of an application into a unique namespace. In C#, this is done with the namespace keyword and the following syntax:

namespace name
{
... type declaration ...
}

In Example 2-1, the HelloWorldService class is placed in the ProgWS.Ch02 namespace with the following statement:

namespace ProgWS.Ch02
{...
}

Namespaces can contain definitions for classes, interfaces, structs, enums, and delegates, as well as other namespaces. In addition, the source code for objects in a namespace does not have to be stored in the same file--it can span multiple files.

Note: For Java programmers: a namespace is similar to a package. However, unlike a package, in a namespace there are no directory structure requirements, because all of the source code is presumed to be in the same directory or a global assembly cache.

Namespaces provide a means of grouping pieces of code that might be written and maintained by other developers. When the class definitions of your web service exist within a namespace, you must specify the namespace along with the class name in your WebService directive as in Example 2-1:

<%@ WebService Language="C#" Class="ProgWS.Ch02.HelloWorldService" %>

This line tells ASP.NET to look for the class HelloWorldService in the namespace ProgWS.Ch02.

The WebService class

At the heart of Example 2-1 is a class called HelloWorldService. This class is a subclass of System.Web.Services.WebService. By inheriting from the WebService class, a web service gains direct access to the ASP.NET intrinsic objects, such as Application and Session, just like any other ASP.NET application.

TIP: While inheriting from the WebService class is a common approach for creating a .NET web service, it is by no means necessary. You can rewrite the previous examples without this inheritance, and your service will run just fine. However, if you need access to the Application and Session objects without inheriting from WebService, you'll need to use the System.Web.HttpContext object explicitly, as we'll explain in a later chapter.

The WebMethod attribute

The HelloWorldService class exposes a single method, the public method HelloWorld, which takes no arguments and returns a string containing the text "Hello World". To expose a method as a part of a web service, you must decorate it with the WebMethod attribute, which tells the compiler to treat it as such. Any method marked with the WebMethod attribute must be defined as public. Class methods exposed as web services follow the same object-oriented rules as any other class, and therefore methods marked private, protected, or internal are not accessible and will return an error if you attempt to expose them using the WebMethod attribute. For additional details, see "The WebMethod Attribute" later in this chapter.

The neat thing about this simple example is that you've created a full-blown web service out of an arbitrary method. You could just as easily have substituted a method that retrieves a record from a data store or a method that wraps a COM object. Additionally, you could have used any of the languages supported by the .NET Framework for this implementation and, then, as you will see later, used any .NET or non-.NET language in a client application. By inheriting from the System.Web.Services.WebService class, you are able to take advantage of an API that insulates you from the underlying SOAP/XML message exchanges.

To put this web service to work, all you need to do is copy it to the web server just as you would any other resource, whether it's an image, HTML file, ASP page, or another resource. Once you've done that, the web service is ready to be used by a consumer application, a process we'll look at in detail in Chapter 3. This ease of deployment is the main benefit of inline coding; perhaps the biggest drawback is that your presentation code and business logic are lumped into the same file, which can make working with large projects difficult to manage. Let's take a look at how Visual Studio .NET can be used to create and deploy this web service without stepping outside its Integrated Development Environment by using the so-called code-behind approach.

Assemblies

We said that a namespace is a container for types such as classes, interfaces, structs, and enums. We also said that the source code for objects in a namespace does not have to be stored in the same file, but can instead span multiple files. When the set of source code constituting a namespace is compiled into a library, this library is called a managed DLL, or, more commonly, an assembly. Assemblies are the building blocks of .NET applications and the fundamental unit of deployment. They comprise a collection of types and resources that provide the CLR (Common Language Runtime) with the information it needs to be aware of type implementations. Their contents can be referenced and used by other applications using Visual Studio .NET or a .NET command-line compiler.

Creating "Hello, World" with Visual Studio .NET

While Notepad is an adequate tool for creating simple services, Microsoft's new development environment, Visual Studio .NET (VS.NET), provides a world of features to aid you in creating complex web services. Visual Studio .NET also provides the quickest path to getting a web service up and running, apart from the time it takes to install all or part of the more than 1.8 GB (compressed) of installation files required to run Visual Studio .NET. This section takes you through the process of creating the "Hello, World" service using Visual Studio .NET.

Setting up VS.NET for the web service project

To make use of the automation in VS.NET, you must first configure it to communicate with your web server. You can use either FrontPage Extensions or Universal Naming Convention (UNC) file shares. To keep things simple, we'll assume you have installed IIS on your local workstation. Here's what you need to do to set up VS.NET for your first web service. We go into detail on FrontPage Extensions and UNC file shares later in this chapter (see "Deploying a Web Service.")

Microsoft FrontPage Server Extensions are the easiest to configure and a good choice for the simple web services in the next two chapters. FrontPage Extensions can be installed as a part of IIS, or alternatively downloaded for free from the MSDN site at http://msdn.microsoft.com. For this example, we're using a Windows 2000 workstation, IIS 5, and FrontPage 2000 Server Extensions, version 4.0.2.4426. While any version of the Extensions will work, the configuration process varies greatly among them and the steps outlined here may not work with your version.

Once you've installed FrontPage Server Extensions on your local workstation (i.e., the workstation hosting IIS), open the Internet Services Manager from the Start Programs Administrative Tools menu so that you can configure a FrontPage web. Right-click on Default Web Site and select All Tasks Configure Server Extensions from the dialog box. You will be taken through a brief configuration wizard that asks you configuration questions. Once the server extensions have been installed, you're ready to create a web service project in Visual Studio .NET.

TIP: With Windows XP, you reach Administrative Tools and the IIS Manager through he Control Panel.

Creating a C# web service project

Visual Studio 6.0 users will find the layout of Visual Studio .NET familiar enough that they can get working without much assistance. We'll help users who are new to Visual Studio. Users new to Visual Studio .NET can also rely on its extensive built-in Help feature.

To create a new web service, fire up Visual Studio .NET and either select the New Project button on the default Start Page or click File New Project on the main Visual Studio .NET menu bar. The Visual Studio project model is the same as earlier versions, in that a file can be part of a project, and a project part of a solution. A solution is the outermost container, containing zero or more projects. After selecting an option to create a new project, you'll see the screen in Figure 2-1.

Figure 2-1. Creating a new Visual Studio project

 

Here you have the option to create a variety of project types from templates. Under Visual C# Projects, one template option creates an ASP.NET web service, while our examples use the C# language, the same option also available as a Visual Basic project, and similar options for Managed C++ exist as well. In addition to selecting a project language and template, you must specify a project name and location. The location fior the HelloWorldService should be the URL of the IIS web server you just configured to work with FrontPage Extensions (e.g., http://localhost). For this example, we'll use the project name "HelloWorldService."

Once you click OK, the IDE (Integrated Development Environment) creates a new solution and project and automatically populate the project with several files. The IDE will also create a virtual folder under IIS with the same name as the project name, which, in this case, is HelloWorldService.

Exploring the solution and project

The contents of your new project are displayed in the Solution Explorer window, which should appear on the right side of the VS.NET IDE, as shown in Figure 2-2.

Figure 2-2. The Visual Studio .NET Solution Explorer

 

If the Solution Explorer is not visible, you can open it by selecting Solution Explorer from the View menu (or pressing Ctrl-Alt-L).

When you create a new project without specifying the name of an existing solution, VS.NET creates a new solution whose name is the same as the one you chose for your project. You can see in Figure 2-2 that, in this case, a solution named HelloWorldService has been created; it contains one project, also called HelloWorldService.

Visual Studio .NET also automatically creates several assembly references and files, which are also displayed in the Solution Explorer, as shown in Figure 2-3. In this example, VS.NET has included assembly references to the System, System.Data, System.Web, System.Web.Services, and System.XML namespaces. (The System.Data and System.XML assembly references are not necessary for this example, so you can remove them if you'd like, but there's no real benefit to doing so other than simplicity.)

Figure 2-3. Displaying all files in VS.NET Solution Explorer

 

The five other files that appear in Figure 2-3 are AssemblyInfo.cs, Global.asax, HelloWorldService.vsdisco, Service1.asmx, and Web.config. The only file you really need to create the web service is the .asmx file, which we'll discuss in the next section. The four other files provide additional features and functionality that will help you as you build more complex services, but none of them are necessary for this example. In fact, you can delete all of the non-.asmx files and the service will run just fine (we don't recommend this). Here's a brief explanation of of each of these.

AssemblyInfo.cs
An information file that provides the compiler with metadata (name, version, etc.) about the assemblies in the project.

Global.asax
Customizable to handle application-level events (e.g., Application_OnStart).

HelloWorldService.vsdisco
An XML file used for dynamic discovery of web services. The DISCO specification has been superseded by WS-Inspection and is discussed in Chapter 10.

Web.config
An XML file containing configuration information for the application.

Exploring the .asmx file and service design view

The most important file in our example is the sample service page named Service1.asmx. If you open the page by double-clicking it, Visual Studio .NET displays a blank design page in its main window. If we were dealing with an .aspx ASP.NET web application, this design page could be used to design the user interface for the page, but since we're developing an .asmx web service that will be consumed by a machine rather than a person, this design view is not as useful to us. If you try to add a Windows form component, you'll get an error ("Object reference not set to an instance of an object"), because the web service design view doesn't know what to do with the component. Unlike an ASP.NET web form project, an ASP.NET web service project doesn't include the plumbing to support Windows form components.

You can use the design view to add preprogrammed components to your service from the Visual Studio .NET Toolbox, but you can't do much beyond adding these items, which is just as easily done directly through the code view page (Service1.asmx.cs). Perhaps Microsoft or another vendor will provide more powerful support for drag-and-drop web service design using business-logic components at some point, but as of today, the design view is not very useful. Instead, you can view the source code of your service by right-clicking on the Service1.asmx file in Solution Explorer and selecting View Code. At this point, you'll also want to rename the Service1.asmx file to something more appropriate to the project. You can do this by right-clicking the file in Solution Explorer and selecting Rename from the menu. Change the name to HelloWorldService.asmx.

Displaying all files in Solution Explorer

The .asmx.cs file is not displayed by default in Solution Explorer. To see it, select Show All Files from the Project menu tab (there's also an icon at the top of Solution Explorer to do this). The Solution Explorer view will change to look like Figure 2-3.

This new view displays all of the files associated with the HelloWorldService project. Notice that the Service1.asmx file now has a tree expander icon to the left of it. Click on the icon, and you'll see another file beneath the Service1.asmx file called Service1.asmx.cs. Elsewhere, you'll also notice a folder called \bin, which is used to store the project's compiled assemblies generated by Visual Studio .NET.

Understanding the autogenerated service code

When you create a new ASP.NET web service project, Visual Studio .NET generates some boilerplate code to get you started. The contents of the source file HelloWorldService.asmx.cs should resemble that reproduced in Figure 2-4.

Figure 2-4. Visual Studio .NET boilerplate code

 

This boilerplate code begins by importing several namespaces generally required for web services and by automatically generating namespace and class definitions. In this example, the namespace and class definitions are HelloWorldService and Service1, respectively.

The namespace definition is generated based on the project name, but you will probably want to change to something more suitable (in this case, we're going to continue to use ProgWS.Ch02) depending on your application. The service name is always autogenerated as Service1. Change this to something more appropriate for your application (in this case, we're using HelloWorldService), but you should also remember to change the name of the .asmx page to mirror your service name. Your service will run just fine if the names don't match up, but keeping the naming consistent can help make managing your service easier, particularly if you have a project with a large number of services.

The imported namespaces at the beginning of the code are provided as a convenience, and some of them are unnecessary. Specifically, the System.Data, System.Collections, and System.Diagnostics namespaces are not used at all. The classes of the System.ComponentModel namespace are used only by the web service designer methods, InitializeComponent() and Dispose(), which work in conjunction with a private member variable of type IContainer called components. To see these methods, you need to expand the Component Designer Generated Code region. Since you're most likely not going to need the (limited) features of the web service design view, you can clean house by deleting the entire region. You will be left with code that looks like the following (some comments have been removed to shorten the listing).

using System;
using System.Web;
using System.Web.Services;
 
namespace ProgWS.Ch02
{
public class HelloWorldService : System.Web.Services.WebService
{
public HelloWorldService() {}
// WEB SERVICE EXAMPLE
// The HelloWorld() example service returns the string Hello World
// To build, uncomment the following lines, then save and build the project
// To test this web service, press F5
 
//[WebMethod]
//public string HelloWorld()
//{
//return "Hello World";
//}
}
}

This code should look familiar since it is nearly identical to the code shown in Example 2-1. All you need to do to make it look like the earlier example is to remove the comments in front of the HelloWorld() method and [WebMethod] attribute.

Notice, however, that the WebService directive that was present in the inline code example is missing:

<%@ WebService Language="C#" Class="ProgWS.Ch02.HelloWorldService" %>

Recall that this directive is required to tell the compiler which class file to use as the entry point for the web service. So where is it? When you wrote the inline code example, you included both the directive and the source code for the HelloWorld class in the same file. By contrast, when Visual Studio .NET creates web service code, it separates the WebService directive and the source code using an approach known to ASP.NET developers as code-behind.

Understanding the code-behind model

The code-behind approach to programming web services (as well as ASP.NET web applications) involves separating the WebService directive from the supporting C# code. In this model, the .asmx page contains only one line, the WebService directive, while the supporting source code is placed on its own page, which, in the case of C#, has the file extension .asmx.cs, as in the preceding example. This page must be compiled into an assembly and placed in the \bin directory of your web service before the service can be used. Visual Studio .NET takes care of this process for you automatically when you build your project.

When you send a request to your web service for the first time, ASP.NET reads the WebService directive to find out the name of the class file containing its supporting logic. ASP.NET knows to look for the compiled class in an assembly in the \bin directory of the project. If there are multiple assemblies in the \bin directory, ASP.NET will look through each of them until it finds the appropriate class.

One of the advantages to storing your code in a compiled form is that source code is not left lying around on your production web servers. A malicious user who gains access to the server hosting your application will not easily be able to steal your code (we say "easily" because there are tools for decompiling MSIL). The disadvantage to using the code-behind model is that deployment requires an additional step--compiling the source code--which is not necessary for inline code.

The CodeBehind Attribute

If you find and view the .asmx page that VS.NET automatically generates and places on your server, you'll notice that the WebService directive includes an additional attribute called CodeBehind. (Unfortunately, you cannot view this .asmx page from Visual Studio .NET; instead, you'll need to look at the file placed on your web server in the c:\inetpub\wwwroot\HelloWorldService folder). In our example, it looks like this (except it's all on a single line):

<%@ WebService Language="c#"
Codebehind="HelloWorldService.asmx.cs"
Class="ProgWS.Ch02.HelloWorldService" %>

This unfortunate choice for an attribute name often confuses developers new to ASP.NET, who often assume that it is used in some way by ASP.NET to locate the code-behind file (indeed, the Microsoft Visual Studio documentation would lead you to believe this to be the case). In fact, this is not the case. This attribute is a Visual Studio .NET-specific attribute and is used by VS.NET to match the .asmx page to the associated source code file. This attribute has nothing to do with ASP.NET. In fact, ASP.NET completely ignores this attribute when processing a page request.

TIP: Visual Studio .NET is not designed to support the inline coding model. It's possible for you to use it, but we certainly do not recommend it: you cannot directly create an inline web service in Visual Studio .NET, because when you create a new web service, by default, Visual Studio .NET creates separate .asmx and class files.

To create an inline service using VS.NET, you must create a new text file and change its extension to .asmx. Creating an .asmx page in this manner forces you to write your code in the Visual Studio .NET HTML editor, not the code editor, which does not provide support for color coding, Intellisense, or many of the debugging features. In addition, because the code in the page is not compiled into the project assembly, compile-time errors are not caught until the page is run.

Building the service

Because Visual Studio .NET uses the code-behind model, simply posting the source pages to the server as in the inline example will not work. If you do so, you will get an error when you try to access the service. Instead, it's necessary to save your .asmx page to the server and compile your source code, saving it to the project's \bin directory. VS.NET automates this process for you through its build feature. Once your application is complete, select Build Solution from the Build menu (or press Ctrl-Shift-B) and VS.NET will compile your web service and transfer the .asmx page and associated compiled assembly to the web server for you. If any errors result from the compile, VS.NET will display them in a panel labeled Output at the bottom of the IDE. Once you have successfully built the web service, it's ready to be used.

Testing the Service

Unlike Active Server Pages, web services are not designed to be viewed in a browser. Instead, web services are consumed by a client application using protocols such as HTTP GET/POST, SMTP, or SOAP over HTTP (see Chapter 3 for more information on consuming web services). Some of these protocols, such as SOAP, are more appropriate for server-to-server communication, while others, such as HTTP GET, are more frequently associated with the model of traditional web page access.

A web service that uses HTTP GET as a transport protocol can be accessed in much the same way as a regular web page. All that is necessary to access such a page is to point a web browser to the service endpoint. In our example, the endpoint comes is an .asmx page. But how do you know which protocols HelloWorldService will support, since there is no mention of HTTP or SOAP in the example code? The answer is that, by default, all .NET web services try to support HTTP GET, HTTP POST, and SOAP. We say "try," because in many cases the web service may be too complex for HTTP GET support. Additionally, because web services are applications that expose functionality to web service clients, and as a result have no required graphical user interface, .NET provides a canned web service test page that is displayed when you point your browser to an .asmx page. If you open a browser and type in the URL of the .asmx web service you just created, you'll see the IE test page shown in Figure 2-5.

Figure 2-5. The HelloWorldService test page

 

The page in Figure 2-5 is generated by the .NET HTTP runtime each time it receives a request for an .asmx page. The page template is itself an ASP.NET .aspx page named DefaultWsdlHelpGenerator.aspx and is stored in the \WINNT\Microsoft.NET\Framework\[version]\Config directory on the server that hosts the web service. This page operates just like any other .aspx page (remember that this is the extension for ASP.NET pages) and can be easily customized.

The test page displays the HelloWorldService service name along with the HelloWorld() method and a link to the service description. The service name and any additional information about this service are retrieved through a process called reflection, which uses the System.Reflection namespace to reveal information about existing types via metadata. In fact, if you look at the Page_Load function for the DefaultWsdlHelpGenerator.aspx page (again, in the \WINNT\Microsoft.NET\Framework\[version]\Config directory on the hosting server), you'll see how this process works. If our service contained additional methods that were callable via HTTP, they would be listed as links here as well.

Viewing the Service Description

The runtime also automatically creates a service description from the .asmx page, an XML document that conforms to a specification called Web Service Description Language, or WSDL (pronounced "Wiz-Duhl"). If you click the service description link, you'll see the WSDL page. This page can also be viewed in a browser by appending ?WSDL to the page URL, as in HelloWorldService.cs.asmx?WSDL. The service description for our service is shown in Figure 2-6.

Figure 2-6. The HelloWorldService description

 

You can see that the WSDL document includes information about the service namespaces, protocols supported, data types used, and web methods exposed in an XML-based format. This type of information is particularly important for an application looking to use our service, as you'll see in the next chapter.

The WSDL specification is a linchpin of sorts for the various web service development platforms. As you'll see in Chapter 11, where you'll learn about web service interoperability, web service development platforms must all abide by the same version of WSDL as well as the same version of SOAP if they are to work together (actually, WSDL is not an absolute requirement, but it is necessary for automatic proxy generation, as you'll see in Chapter 3). The version of WSDL we discuss in this book, 1.1, is currently supported by .NET and most other web service implementations (e.g., SOAP::Lite, Apache Axis).[1] The .NET Framework currently implements SOAP 1.1.

Getting back to the service test page: if you mouse over the HelloWorld link, you'll see the destination URL:

http://localhost/HelloWorldService.cs.asmx?op=HelloWorld

By clicking this link, you call the .asmx page, passing a parameter called op (standing presumably for operation) along with the name of the service. This action is the same as calling the HelloWorld web method of the web service using HTTP GET. The output page is shown in Figure 2-7.

Figure 2-7. The HelloWorldService invocation page

 

Here you'll see the name of the service and method along with a button to test the service. Through reflection, the logic in the DefaultWsdlHelpGenerator.aspx test page is able to determine the signature of our HelloWorld method. Because our web method takes no arguments, the page need provide only a button for invocation. If our method had a different signature--for example, if it reads a string of text--the .aspx help page would also provide a text box to capture this string and pass it, using HTTP GET, to the web method when the form was submitted. This text box method works fine for simple data type arguments, but if the web method were to require an object, this approach would not work.

Beneath the Invoke button, there are also sample service interactions for SOAP, HTTP GET, and HTTP POST. We'll talk about some of the other methods of consuming web services in Chapter 3, but for now, note that on the source, the page is still using HTTP GET to invoke our service.

<form 
action='http://localhost/HelloWorldService/HelloWorldService.cs.asmx/HelloWorld'
method="GET">
...
</form>

Invoking the Web Method

You can invoke the web method using the IE test page by opening a web browser and navigating to the service's URL. You will see a page listing the service's operation, which should be HelloWorld. Click the HelloWorld operation to navigate to the web method invocation page. This is a page that allows you to test the operation by clicking a button labeled Invoke. Click the button to invoke the service.

Invoking the example service produces the results shown in Figure 2-8.

Figure 2-8. HelloWorldService output

 

You know that web services are a means of communicating between servers using XML, so it should come as no surprise that the output of our service is nothing more than an XML document--and a short one at that! Had you used SOAP to access the service, you would have received a message in SOAP format; however, since IE isn't designed to either write or read SOAP messages by itself, you're limited to using HTTP GET and POST.

The response document begins with the following XML declaration:

<?xml version="1.0" encoding="utf-8" ?>

which identifies the document as an XML document and identifies the encoding of the document to be UTF-8 Unicode. While the encoding type may vary, all XML processors are required to support UTF-8 and UTF-16 Unicode encodings.

The first and only element in the output document is an element called string, which contains the output of our method and has one attribute called xmlns:

xmlns="http://tempuri.org"

This namespace declaration specifies that all unprefixed elements in this document come from the namespace tempuri.org.

The WebService Attribute

One of the features missing from our HelloWorld web service is information about what it does. To tell a client about the functionality provided by our service, we need some mechanism for documenting it. .NET provides an attribute for this purpose, WebServiceAttribute (a member of the System.Web.Services namespace), which you can use to let clients know where to find information about a web service. As with other attribute types, the WebServiceAttribute class inherits from System.Attribute. For convenience, the compiler will let you omit the Attribute part of the class name in most usage contexts, allowing you to use just WebService instead (not to be confused with the WebService directive in an .asmx page). For simplicity, we'll leave off the Attribute part as well throughout this text. The WebService attribute has two properties, described next.

Namespace
Sets the XML namespace for the service

Description
Adds a text/HTML description of the service that becomes part of the service description (WSDL) document

As discussed earlier, XML namespaces are important in the XML world for uniquely identifying the elements and attributes of an XML document. XML namespaces have nothing to do with the .NET's namespaces, which are used to organize classes.

Example 2-2 uses the Namespace and Description properties of the WebService attribute to document a web service named DNSLookUpService, which we introduce here for the first time. DNSLookUpService takes a hostname as a string argument and uses a class called Dns from the System.Net namespace to resolve and return the associated IP address.

Example 2-2: DNS LookupService

using System.Web.Services;
using System.Net;
[WebService(Namespace="http://www.bostontechnical.com/webservices/",
Description="<b>A web service which performs Do

抱歉!评论已关闭.