ASP.NET Web Services or .NET Remoting: How to Choose

 

Priya Dhawan
Tim Ewald
Microsoft Developer Network

September 2002

Applies to:
   Microsoft® ASP.NET Web services
   Microsoft® .NET Framework
   Microsoft® .NET Remoting

Summary: Understand how the Microsoft .NET Remoting infrastructure and Microsoft ASP.NET Web services can enable cross-process communication, how both technologies work, and how to choose the one that is right for your application. (12 printed pages)

Contents

Overview
Serialization and Metadata
Distributed Application Design: ASP.NET Web Services vs. .NET Remoting
Choosing an Architecture
Summary

Overview

Over time, it has become common practice to build applications as a set of components that are distributed across a network of machines and work together as part of one overall program. Traditionally, distributed application logic called for component-object technology such as the Microsoft® Distributed Component Object Model (DCOM), the Object Management Group's Common Object Request Broker Architecture (CORBA), or Sun's Remote Method Invocation (RMI). These technologies provided reliable, scalable architecture to meet the growing needs of applications.

Though these component-based technologies work very well in an intranet environment, attempting to use them over the Internet presents two significant problems. First, the technologies do not interoperate. While they all dealt with objects, they disagreed over the details, for example, lifecycle management, support for constructors, and degree of support for inheritance. Second, and more important, their focus on RPC-style communication typically led to tightly coupled systems built around the explicit invocations of object methods.

Browser-based Web applications, in contrast, are loosely coupled and remarkably interoperable. They communicate using HTTP to exchange MIME-typed data in a wide range of formats. Web services adapt the traditional Web programming model for use from all sorts of applications, not just browser-based ones. They exchange SOAP messages using HTTP and other Internet protocols. Because Web services rely on industry standards, including HTTP, XML, SOAP and WSDL, to expose application functionality on the Internet, they are independent of programming language, platform and device.

The ASP.NET Web services infrastructure provides a simple API for Web services based on mapping SOAP messages to method invocations. It accomplishes this by providing a very simple programming model based on mapping SOAP message exchanges to individual method invocations. The clients of ASP.NET Web services do not have to know anything about the platform, object model, or programming language used to build them. The services themselves don't have to know anything about the clients that are sending them messages. The only requirement is that both parties agree on the format of the SOAP messages being produced and consumed, as defined by the Web service's contract definition expressed using WSDL and XML Schema (XSD).

.NET Remoting provides an infrastructure for distributed objects. It exposes the full-object semantics of .NET to remote processes using plumbing that is both very flexible and extensible. Compared to ASP.NET Web services, which provide a very simple programming model based on message passing, .NET Remoting offers much more complex functionality, including support for passing objects by value or by reference, callbacks, and multiple-object activation and lifecycle management policies. In order to use .NET Remoting, a client needs to be aware of all these details—in short the client needs to be built using .NET. (Or with another framework that supports .NET Remoting; the only one we are aware of is Intrinsyc's Ja.NET for Java.) The .NET Remoting plumbing also supports SOAP messages, but it is important to note that this doesn't change its client requirements. If a Remoting endpoint exposes .NET-specific object semantics, via SOAP or not, the client must understand them.

The fact that the .NET Framework includes support for two distinct distributed programming models, Web services and distributed objects, has caused a fair amount of confusion for developers. When should a system use ASP.NET Web services and when should it use .NET Remoting? To answer this question, you have to understand how both these technologies really work.

Serialization and Metadata

All distributed communication plumbing ultimately does two things: it marshals instances of programmatic data types into messages that can be sent across the network, and it provides a description of what those messages look like. The former is accomplished using some form of serialization engine, or marshaler. The latter is achieved through some form of metadata. For instance, for most (latter day) DCOM interfaces, the serialization engine was the Type Library Marshaler and type libraries provided the metadata. The key difference between ASP.NET Web services and .NET Remoting is in how they serialize data into messages and the format they choose for metadata.

ASP.NET Web Services, XmlSerializer and XSD

ASP.NET Web services rely on the System.Xml.Serialization.XmlSerializer class to marshal data to and from SOAP messages at runtime. For metadata, they generate WSDL and XSD definitions that describe what their messages contain. The reliance on pure WSDL and XSD makes ASP.NET Web services metadata portable; it expresses data structures in a way that other Web service toolkits on different platforms and with different programming models can understand. In some cases, this imposes constraints on the types you can expose from a Web service—XmlSerializer will only marshal things that can be expressed in XSD. Specifically, XmlSerializer will not marshal object graphs and it has limited support for container types.

Though these limitations may seem significant from a classic distributed object perspective, they help ensure interoperability with other Web service frameworks—a basic goal of the loosely coupled Web service model. Support for interoperability is augmented by a rich set of custom attributes that allow you to annotate your data types to control the way in which the XmlSerializer marshals them. As a result, you have very fine-grained control over the shape of the XML being generated when an object is serialized. In addition, an ASP.NET-based Web service can be tailored to describe its messages in terms of literal XSD or the SOAP encoding rules (i.e., SOAP Section 5). Literal XSD is the default, and will be the standard going forward. SOAP-encoding support is included for interoperability with existing toolkits. This is beneficial, especially when you need to communicate with an existing Web service or client that needs to communicate using a predefined message format.

.NET Remoting, IFormatter and the Common Language Runtime

.NET Remoting relies on the pluggable implementations of the IFormatter interface used by the System.Runtime.Serialization engine to marshal data to and from messages. There are two standard formatters, System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and System.Runtime.Serialization.Formatters.Soap.SoapFormatter. The BinaryFormatter and SoapFormatter, as the names suggest, marshal types in binary and SOAP format respectively. For metadata, .NET Remoting relies on the common language runtime assemblies, which contain all the relevant information about the data types they implement, and expose it via reflection. The reliance on the assemblies for metadata makes it easy to preserve the full runtime type-system fidelity. As a result, when the .NET Remoting plumbing marshals data, it includes all of a class's public and private members; handles object graphs correctly; and supports all container types (e.g., System.Collections.Hashtable). However, the reliance on runtime metadata also limits the reach of a .NET Remoting system—a client has to understand .NET constructs in order to communicate with a .NET Remoting endpoint. In addition to pluggable formatters, the .NET Remoting layer supports pluggable channels, which abstract away the details of how messages are sent. There are two standard channels, one for raw TCP and one for HTTP. Messages can be sent over either channel independent of format.

Muddying the Water: Remoting and Web Services

The presence of a SOAP formatter and an HTTP channel begs the question: Can .NET Remoting be used to build Web services? The answer is yes and no. The standard Web service technology stack relies not only on SOAP-based messages, but also on WSDL- and XSD-based descriptions of those messages. The Remoting plumbing can actually generate WSDL definitions that describe the messages an endpoint produces and consumes. However, several issues arise if you go down this path.

First, the generated WSDL files always describe messages in terms of the SOAP-encoding rules instead of literal XSD. This isn't a problem today, but it will be going forward as more and more tools focus entirely on schemas.

Second, the generated WSDL files include extensions that are .NET Remoting-specific. For instance, here is a simple class that uses .NET Remoting to expose its behavior.

public class Methods : MarshalByRefObject
{
// The Now method returns the current date and time
public string Now()
{
return System.DateTime.Now.ToString();
}
}

If you generate WSDL from this class, the binding information includes .NET Remoting-specific details, as shown below.

<binding name='MethodsBinding' type='ns0:MethodsPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<suds:class type='ns0:Methods' rootType='MarshalByRefObject'>
</suds:class>
<operation name='Now'>
<soap:operation soapAction=
'http://schemas.microsoft.com/clr/nsassem/RemSoap.Methods/methods#Now'/>
<suds:method attributes='public'/>
<input name='NowRequest'>...</input>
<output name='NowResponse'>...</output>
</operation>
</binding>

These extra elements are legal because the WSDL specification supports extensibility. Any well-behaved Web service toolkit that doesn't understand them should simply ignore them. However, there are some things a Web service toolkit cannot ignore. For instance, here is a Remoting endpoint that returns a Microsoft® ADO.NET System.Data.DataSet.

public class Methods : MarshalByRefObject
{
public System.Data.DataSet GetEmptyDataSet()
{
return new System.Data.DataSet();
}
}

Here is the generated WSDL definition for this method's output message:

<message name='Methods.GetEmptyDataSetOutput'>
<part name='return' type='ns3:DataSet'/>
</message>

Normally, a WSDL message refers to types defined in a particular namespace using XML Schema. In this case, however, the namespace prefix ns3 applied to the DataSet type is not defined in XSD. Instead it is implicitly defined via the runtime. The ns3 prefix in this example is bound to an XML namespace identified by this URI:

http://schemas.microsoft.com/clr/nsassem/System.Data/System.Data%2C%20Version%3D1.0.3300.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db77a5c561934e089

Consumers of this WSDL definition are meant to understand the special significance of this "well-known" URI—it is the four-part strong name of a specific runtime assembly included in the .NET Framework. This style of WSDL is great for clients that are implemented using .NET Remoting because they can generate a proxy assembly with the right information for marshaling. However, for other Web service toolkits—including ASP.NET—that do not understand this URI and expect to find a schema definition for the DataSet type, this WSDL will be useless.

So the question remains, can you use .NET Remoting to build Web services? Yes, strictly speaking, you can. But, will anybody who is not using the .NET Remoting plumbing be able to use them? The answer is maybe, if you are careful to pare down your endpoint to bare bones data types and semantics. Specifically, if you want interoperability with other Web service toolkits, you need to restrict parameters to the built-in simple types and your own data types (don't use .NET Framework types like DataSet), and avoid client-activated objects and events. In short, if you care about reach, you need to restrict yourself to the same set of functionality that ASP.NET Web services support.

Or better yet, use ASP.NET Web Services, because this is exactly what they are designed for.

Distributed Application Design: ASP.NET Web Services vs. .NET Remoting

ASP.NET Web services favor the XML Schema type system, and provide a simple programming model with broad cross-platform reach. .NET Remoting favors the runtime type system, and provides a more complex programming model with much more limited reach. This essential difference is the primary factor in determining which technology to use. However, there are a wide range of other design factors, including transport protocols, host processes, security, performance, state management, and support for transactions to consider as well.

Transport Protocols and Host Processes

Although the SOAP specification does not mandate HTTP as the transport protocol, the client can access Web services implemented using ASP.NET Web services only over HTTP, because it is the only transport protocol ASP.NET supports. The services are invoked via IIS and execute in the ASP.NET worker process, aspnet_wp.exe.

.NET Remoting gives you the flexibility to host remote objects in any type of application including a Windows Form, a managed Windows Service, a console application or the ASP.NET worker process. As previously noted, .NET Remoting provides two transport channels—TCP and HTTP. Both channels provide communication between arbitrary sending and receiving processes using sockets.

It is also possible to integrate the HTTP channel with IIS and the ASP.NET worker process. This is important for several reasons. First, it is the only way to auto-start a .NET Remoting endpoint when a client request arrives. The .NET Remoting plumbing does not include a DCOM style Service Control Manager (SCM) to start remote servers. If you expose remote objects from arbitrary processes, you have to ensure those process are running. You also have to ensure they are thread-safe, e.g., that thread A can't activate an object after thread B started to shut the process down. If you expose remote objects from ASP.NET, you can take advantage of the fact that the Aspnet_wp.exe worker process is both auto-starting and thread-safe. Second, as described in the next section, integration with IIS is the only way you can secure a cross-process .NET Remoting call.

Both the ASP.NET Web services and the .NET Remoting infrastructures are extensible. You can filter inbound and outbound messages, control aspects of type marshaling and metadata generation. With .NET Remoting, you can also implement your own formatters and channels.

Security

Since ASP.NET Web services rely on HTTP, they integrate with the standard Internet security infrastructure. ASP.NET leverages the security features available with IIS to provide strong support for standard HTTP authentication schemes including Basic, Digest, digital certificates, and even Microsoft® .NET Passport. (You can also use Windows Integrated authentication, but only for clients in a trusted domain.) One advantage of using the available HTTP authentication schemes is that no code change is required in a Web service; IIS performs authentication before the ASP.NET Web services are called. ASP.NET also provides support for .NET Passport-based authentication and other custom authentication schemes. ASP.NET supports access control based on target URLs, and by integrating with the .NET code access security (CAS) infrastructure. SSL can be used to ensure private communication over the wire.

Although these standard transport-level techniques to secure Web services are quite effective, they only go so far. In complex scenarios involving multiple Web services in different trust domains, you have to build custom ad hoc solutions. Microsoft and others are working on a set of security specifications that build on the extensibility of SOAP messages to offer message-level security capabilities. One of these is the XML Web Services Security Language (WS-Security), which defines a framework for message-level credential transfer, message integrity, and message confidentiality.

As noted in the previous section, the .NET Remoting plumbing does not secure cross-process invocations in the general case. A .NET Remoting endpoint hosted in IIS with ASP.NET can leverage all the same security features available to ASP.NET Web services, including support for secure communication over the wire using SSL. If you are using the TCP channel or the HTTP channel hosted in processes other than aspnet_wp.exe, you have to implement authentication, authorization and privacy mechanisms yourself.

One additional security concern is the ability to execute code from a semi-trusted environment without having to change the default security policy. ASP.NET Web Services client proxies work in these environments, but .NET Remoting proxies do not. In order to use a .NET Remoting proxy from a semi-trusted environment, you need a special serialization permission that is not given to code loaded from your intranet or the Internet by default. If you want to use a .NET Remoting client from within a semi-trusted environment, you have to alter the default security policy for code loaded from those zones. In situations where you are connecting to systems from clients running in a sandbox—like a downloaded Windows Forms application, for instance—ASP.NET Web Services are a simpler choice because security policy changes are not required.

State Management

The ASP.NET Web Services model assumes stateless service architecture by default; it does not inherently correlate multiple calls from the same user. In addition, each time a client invokes an ASP.NET Web service, a new object is created to service the request. The object is destroyed after the method call completes. To maintain state between requests, you can either use the same techniques used by ASP.NET pages, i.e., the Session and Application property bags, or you can implement your own custom solution.

.NET Remoting supports a range of state management options and may or may not correlate multiple calls from the same user, depending on what object lifetime scheme you choose. SingleCall objects are stateless (like the objects used to invoke ASP.NET Web services), Singleton objects share state for all clients, and client-activated objects maintain state on a per-client basis (with all the associated scalability and reliability issues this raises).

Performance

In terms of raw performance, the .NET Remoting plumbing provides the fastest communication when you use the TCP channel and the binary formatter. In almost all the tests that we carried out to compare the relative performance of ASP.NET Web services and .NET Remoting, ASP.NET Web services outperformed .NET Remoting endpoints that used the SOAP formatter with either the HTTP or the TCP channel. More interestingly, ASP.NET and .NET Remoting endpoints that used the binary formatter and the HTTP channel were very similar in performance. (See Performance Comparison: .NET Remoting vs. ASP.NET Web Services for more details.)

Enterprise Services

An ASP.NET Web Service or an object exposed via .NET Remoting can use local transactions to coordinate work against a single database. If it needs to coordinate work against multiple resources, it can use a .NET Enterprise Services (a.k.a. COM+) declarative transaction (a DTC distributed transaction managed by the COM+ plumbing). It is important to note, however, that neither the ASP.NET Web services nor the .NET Remoting plumbing supports propagating a declarative transaction, so it is impossible for either sort of endpoint to inherit a declarative transaction via a cross-process call.

This is not necessarily a bad thing. In general, a declarative transaction is more expensive than a local transaction and if you spread a declarative transaction across process boundaries, it becomes more expensive still. If you really need this functionality, the easy solution is to deploy a class derived from System.EnterpriseServices.ServicedComponent in a .NET Enterprise Services server application (see COM+ Integration: How .NET Enterprise Services Can Help You Build Distributed Applications for more information). Cross-process calls to the objects of that type will be handled using DCOM in order to ensure proper propagation of transactional context. The harder solution is to use lower-level APIs to propagate a distributed transaction by hand.

It is important to note that the classic distributed transaction model is generally not appropriate for loosely coupled Web services. A model based on compensating transactions, that is, transactions that undo the committed work of other transactions, make more sense because they have less stringent isolation constraints. There is a general consensus among Web service vendors, including Microsoft, that a more flexible transaction model is needed in the Web services space, and there is a lot of ongoing work in this space. Until a standard approach for Web service transactions is defined, you can implement your own compensation schemes using local or declarative transactions as appropriate.

Choosing an Architecture

If you are designing a distributed application built on .NET, you have to consider all of the issues discussed in this paper and draw some conclusions about what your system's architecture should look like. In general, this turns out to be easier than you might think. While there is always a special case that requires an alternate approach, here are some general assumptions you can make that will simplify things for you.

First, use ASP.NET Web services by default. They are simpler to implement and use, they offer the broadest possible reach to client platforms, and ASP.NET Web services client proxy code can be invoked from code run in a sandbox under the default security policy.

If you need a more traditional distributed object model with full CLR type fidelity, you don't need interoperability with other platforms, and you control the configuration of both clients and servers, consider .NET Remoting. If you choose .NET Remoting, prefer the HTTP channel integrated with IIS and ASP.NET, otherwise you have to build your own process lifecycle management and security infrastructure. Given that .NET Remoting requires a .NET client, it makes sense to use the binary formatter instead of the SOAP formatter; interoperability is not an issue and performance will be noticeably better.

Finally, use Enterprise Services (COM+) when you need declarative transactions. If you implement ServicedComponents, deploy them in library applications by default, for performance reasons. Deploy them in server applications if they need to run on remote machines. (You might also consider COM+ server applications if you need to execute code with a different process security token than the one used by aspnet_wp.exe, even on the same machine.)

Here are three common architectures based on these ideas.

ms978420.bdadotnetarch16_01(en-us,MSDN.10).gif

Figure 1. A simple 3-tier architecture

Figure 1 shows a simple 3-tier architecture with a Web server farm supporting a range of different clients. All server-side code executes in the ASP.NET worker process, aspnet_wp.exe. The three different types of clients access the server farm by using HTTP. Browser-based clients invoke ASP.NET Web pages; rich clients (e.g., Windows Forms applications, Microsoft® Visual Basic® 6 applications) and other Web services use ASP.NET Web services; and .NET rich clients (e.g., Windows Forms applications) and Web services use ASP.NET Web services or .NET Remoting with the HTTP channel and the binary formatter (assuming it is not in a sandbox), as desired.

ms978420.bdadotnetarch16_02(en-us,MSDN.10).gif

Figure 2. An n-tier architecture using ASP.NET

Some very large applications use a second set of machines to offload work from the outer tier of Web servers. This architecture is shown in Figure 2. Note that in this case, the second tier exposes functionality through ASP.NET as well.

ms978420.bdadotnetarch16_03(en-us,MSDN.10).gif

Figure 3. An n-tier architecture using Enterprise Services (COM+)

Figure 3 shows an alternative version of this architecture with the second tier exposing functionality using ServicedComponents deployed in COM+.

Obviously, these are not all of the possible architectures that the .NET Framework supports. However, they provide a reasonable place to start in the design of your own systems.

Summary

Though both the .NET Remoting infrastructure and ASP.NET Web services can enable cross-process communication, each is designed to benefit a different target audience. ASP.NET Web services provide a simple programming model and a wide reach. .NET Remoting provides a more complex programming model and has a much narrower reach. It is important to understand how both technologies work and to choose the one that is right for your application. In either case, expect to use IIS and ASP.NET to manage process lifecycle and provide security in the general case

posted on 2010-12-29 22:34  Jason Li 2011  阅读(390)  评论(0编辑  收藏  举报