Migrieren von .NET-Remoting zu WCFMigrating from .NET Remoting to WCF

Dieser Artikel beschreibt die Vorgehensweise zum Migrieren einer Anwendung, die .NET Remoting zur Verwendung von Windows Communication Foundation (WCF) nutzt.This article describes how to migrate an application that uses .NET Remoting to use Windows Communication Foundation (WCF). Es werden ähnliche Konzepte dieser zwei Produkte verglichen, und es wird beschrieben, wie verschiedene Remoting-Szenarien in WCF realisiert werden können.It compares similar concepts between these products and then describes how to accomplish several common Remoting scenarios in WCF.

.NET Remoting ist ein Legacy-Produkt, das nur zur Bereitstellung von Abwärtskompatibilität unterstützt wird..NET Remoting is a legacy product that is supported only for backward compatibility. Seine Verwendung in Umgebungen mit gemischten Vertrauensstellungen ist nicht sicher, da keine getrennten Vertrauensebenen zwischen Client und Server eingerichtet werden können.It is not secure across mixed-trust environments because it cannot maintain the separate trust levels between client and server. Beispielsweise sollten Sie nie einen .NET Remoting-Endpunkt für das Internet oder nicht vertrauenswürdige Clients verfügbar machen.For example, you should never expose a .NET Remoting endpoint to the Internet or to untrusted clients. Es wird empfohlen, vorhandene Remoting-Anwendungen auf neuere und sicherere Technologien zu migrieren.We recommend existing Remoting applications be migrated to newer and more secure technologies. Wenn das Anwendungsdesign nur HTTP und RESTful verwendet, wird die ASP.NET-Web-API empfohlen.If the application’s design uses only HTTP and is RESTful, we recommend ASP.NET Web API. Weitere Informationen finden Sie unter "ASP.NET-Web-API".For more information, see ASP.NET Web API. Wenn die Anwendung auf SOAP basiert oder Nicht-HTTP-Protokolle wie z. B. TCP erfordert, empfehlen wir WCF.If the application is based on SOAP or requires non-Http protocols such as TCP, we recommend WCF.

Vergleich von .NET Remoting und WCFComparing .NET Remoting to WCF

In diesem Abschnitt werden die grundlegenden Bausteine von .NET Remoting mit ihren Entsprechungen in WCF verglichen.This section compares the basic building blocks of .NET Remoting with their WCF equivalents. Diese Bausteine werden später verwendet, um einige gängige Client/Server-Szenarien in WCF zu erstellen. Das folgende Diagramm zeigt die wichtigsten Ähnlichkeiten und Unterschiede zwischen .NET Remoting und WCF.We will use these building blocks later to create some common client-server scenarios in WCF.The following chart summarizes the main similarities and differences between .NET Remoting and WCF.

.NET-Remotezugriff.NET Remoting WCFWCF
ServertypServer type MarshalByRefObject-UnterklasseSubclass MarshalByRefObject Markierung mit [ServiceContract]-AttributMark with [ServiceContract] attribute
DienstvorgängeService operations Öffentliche Methoden für ServertypPublic methods on server type Markierung mit [OperationContract]-AttributMark with [OperationContract] attribute
SerialisierungSerialization ISerializable oder [Serializable]ISerializable or [Serializable] DataContractSerializer oder XmlSerializerDataContractSerializer or XmlSerializer
Übergebene ObjekteObjects passed Als Wert oder VerweisBy-value or by-reference Nur als WertBy-value only
Fehler/AusnahmenErrors/exceptions Jede serialisierbare AusnahmeAny serializable exception FaultContract<TDetail>FaultContract<TDetail>
ClientproxyobjekteClient proxy objects Stark typisierte transparente Proxys werden automatisch über MarshalByRefObjects erstelltStrongly typed transparent proxies are created automatically from MarshalByRefObjects Stark typisierte Proxys werden generiert, bei Bedarf über ChannelFactory<TChannel >Strongly typed proxies are generated on-demand using ChannelFactory<TChannel>
Plattform erforderlichPlatform required Client und Server müssen Microsoft-Betriebssystem und .NET verwendenBoth client and server must use Microsoft OS and .NET PlattformübergreifendCross-platform
NachrichtenformatMessage format PrivatPrivate Industriestandards (SOAP, WS-* usw.)Industry standards (SOAP, WS-*, etc.)

Serverimplementierung im VergleichServer Implementation Comparison

Erstellen eines Servers in .NET RemotingCreating a Server in .NET Remoting

.NET Remoting-Servertypen müssen von MarshalByRefObject abgeleitet werden und Methoden definieren, die der Client aufrufen kann. Dies wird nachfolgend gezeigt:.NET Remoting server types must derive from MarshalByRefObject and define methods the client can call, like the following:

public class RemotingServer : MarshalByRefObject  
{  
    public Customer GetCustomer(int customerId) { … }  
}  

Die öffentlichen Methoden dieses Servertyps werden zum öffentlichen Vertrag, der für Clients zur Verfügung steht.The public methods of this server type become the public contract available to clients. Es gibt keine Trennung zwischen der öffentlichen Serverschnittstelle und deren Implementierung – beide werden durch einen Typ behandelt.There is no separation between the server’s public interface and its implementation – one type handles both.

Nachdem der Servertyp definiert wurde, kann er für Clients verfügbar gemacht werden, wie im folgenden Beispiel gezeigt:Once the server type has been defined, it can be made available to clients, like in the following example:

TcpChannel channel = new TcpChannel(8080);  
ChannelServices.RegisterChannel(channel, ensureSecurity : true);  
RemotingConfiguration.RegisterWellKnownServiceType(  
    typeof(RemotingServer),   
    "RemotingServer",   
    WellKnownObjectMode.Singleton);  
Console.WriteLine("RemotingServer is running.  Press ENTER to terminate...");  
Console.ReadLine();  

Es gibt viele Möglichkeiten, den Remoting-Typ als Server verfügbar zu machen, einschließlich der Verwendung von Konfigurationsdateien.There are many ways to make the Remoting type available as a server, including using configuration files. Dies ist nur ein Beispiel.This is just one example.

Erstellen eines Servers in WCFCreating a Server in WCF

Der entsprechende Schritt in WCF umfasst das Erstellen von zwei Typen – des öffentlichen "Dienstvertrags" und der konkreten Implementierung.The equivalent step in WCF involves creating two types -- the public "service contract" and the concrete implementation. Der erste Typ wird als eine mit [ServiceContract] markierte Schnittstelle deklariert.The first is declared as an interface marked with [ServiceContract]. Für Clients verfügbare Methoden sind mit [OperationContract] markiert:Methods available to clients are marked with [OperationContract]:

[ServiceContract]  
public interface IWCFServer  
{  
    [OperationContract]  
    Customer GetCustomer(int customerId);  
}  

Die serverseitige Implementierung ist in einer separaten konkreten Klasse definiert, wie im folgenden Beispiel gezeigt:The server’s implementation is defined in a separate concrete class, like in the following example:

public class WCFServer : IWCFServer  
{  
    public Customer GetCustomer(int customerId) { … }  
}  

Sobald diese Typen definiert wurden, kann der WCF-Server für Clients verfügbar gemacht werden, wie im folgenden Beispiel gezeigt:Once these types have been defined, the WCF server can be made available to clients, like in the following example:

NetTcpBinding binding = new NetTcpBinding();  
Uri baseAddress = new Uri("net.tcp://localhost:8000/wcfserver");  

using (ServiceHost serviceHost = new ServiceHost(typeof(WCFServer), baseAddress))  
{  
    serviceHost.AddServiceEndpoint(typeof(IWCFServer), binding, baseAddress);  
    serviceHost.Open();  

    Console.WriteLine(String.Format("The WCF server is ready at {0}.",  
                                    baseAddress));  
    Console.WriteLine("Press <ENTER> to terminate service...");  
    Console.WriteLine();  
    Console.ReadLine();  
}  

Hinweis

Es wird in beiden Fällen TCP verwendet, um die Beispiele so ähnlich wie möglich zu halten.TCP is used in both examples to keep them as similar as possible. Beispiele mit Verwendung von HTTP finden Sie weiter unten in diesem Thema in den Szenariobeschreibungen.Refer to the scenario walk-throughs later in this topic for examples using HTTP.

Es gibt viele Möglichkeiten zum Konfigurieren und Hosten von WCF-Diensten.There are many ways to configure and to host WCF services. Dies ist lediglich ein Beispiel, bezeichnet als "selbst gehosteter Dienst".This is just one example, known as "self-hosted". Weitere Informationen finden Sie unter den folgenden Themen:For more information, see the following topics:

Clientimplementierung im VergleichClient Implementation Comparison

Erstellen eines Clients in .NET RemotingCreating a Client in .NET Remoting

Sobald ein .NET Remoting-Serverobjekt verfügbar gemacht wurde, kann es von Clients genutzt werden, wie im folgenden Beispiel gezeigt:Once a .NET Remoting server object has been made available, it can be consumed by clients, like in the following example:

TcpChannel channel = new TcpChannel();  
ChannelServices.RegisterChannel(channel, ensureSecurity : true);  
RemotingServer server = (RemotingServer)Activator.GetObject(  
                            typeof(RemotingServer),   
                            "tcp://localhost:8080/RemotingServer");  

RemotingCustomer customer = server.GetCustomer(42);  
Console.WriteLine(String.Format("Customer {0} {1} received.",   
                                 customer.FirstName, customer.LastName));  

Die von Activator.GetObject() zurückgegebene RemotingServer-Instanz wird als "transparenter Proxy" bezeichnet.The RemotingServer instance returned from Activator.GetObject() is known as a "transparent proxy." Diese Instanz implementiert die öffentliche API für den RemotingServer-Typ auf dem Client, sämtliche Methoden rufen jedoch das Serverobjekt auf, das in einem anderen Prozess oder auf einem anderen Computer ausgeführt wird.It implements the public API for the RemotingServer type on the client, but all the methods call the server object running in a different process or machine.

Erstellen eines Clients in WCFCreating a Client in WCF

Der entsprechende Schritt in WCF umfasst die Verwendung einer Kanalfactory zur expliziten Erstellung des Proxys.The equivalent step in WCF involves using a channel factory to create the proxy explicitly. Wie Remoting kann das Proxyobjekt zum Auslösen von Vorgängen auf dem Server verwendet werden, wie im folgenden Beispiel gezeigt:Like Remoting, the proxy object can be used to invoke operations on the server, like in the following example:

NetTcpBinding binding = new NetTcpBinding();  
String url = "net.tcp://localhost:8000/wcfserver";  
EndpointAddress address = new EndpointAddress(url);  
ChannelFactory<IWCFServer> channelFactory =   
    new ChannelFactory<IWCFServer>(binding, address);  
IWCFServer server = channelFactory.CreateChannel();  

Customer customer = server.GetCustomer(42);  
Console.WriteLine(String.Format("  Customer {0} {1} received.",  
                    customer.FirstName, customer.LastName));  

Dieses Beispiel zeigt die Programmierung auf Kanalebene, da sie dem Remoting-Beispiel am ähnlichsten ist.This example shows programming at the channel level because it is most similar to the Remoting example. Auch verfügbar ist die Hinzufügen eines Dienstverweises Ansatz in Visual Studio, der Code zur Vereinfachung der Clientprogrammierung generiert.Also available is the Add Service Reference approach in Visual Studio that generates code to simplify client programming. Weitere Informationen finden Sie unter den folgenden Themen:For more information, see the following topics:

Verwenden der SerialisierungSerialization Usage

Sowohl .NET Remoting als auch WCF verwenden Serialisierung, um Objekte zwischen Client und Server zu senden. Es gelten jedoch folgende wichtige Unterschiede:Both .NET Remoting and WCF use serialization to send objects between client and server, but they differ in these important ways:

  1. Sie verwenden verschiedene Serialisierer und Konventionen, um anzugeben, was serialisiert werden soll.They use different serializers and conventions to indicate what to serialize.

  2. .NET Remoting unterstützt die Serialisierung "nach Verweis", bei der ein Methoden- oder Eigenschaftenzugriff auf einer Ebene die Ausführung von Code auf einer anderen Ebene zulässt, also über Sicherheitsgrenzen hinweg..NET Remoting supports "by reference" serialization that allows method or property access on one tier to execute code on the other tier, which is across security boundaries. Diese Funktion birgt Sicherheitsrisiken und ist einer der Hauptgründe dafür, warum Remoting-Endpunkte niemals für nicht vertrauenswürdige Clients verfügbar gemacht werden sollten.This capability exposes security vulnerabilities and is one of the main reasons why Remoting endpoints should never be exposed to untrusted clients.

  3. Die von Remoting eingesetzte Serialisierung erfolgt nach dem Ausschlussverfahren (expliziter Ausschluss der Elemente, die nicht serialisiert werden sollen), WCF verwendet eine Serialisierung nach dem Einschlussverfahren (explizite Markierung der Elemente, die serialisiert werden sollen).Serialization used by Remoting is opt-out (explicitly exclude what not to serialize) and WCF serialization is opt-in (explicitly mark which members to serialize).

Serialisierung in .NET RemotingSerialization in .NET Remoting

.NET Remoting unterstützt zwei Möglichkeiten zum Serialisieren und Deserialisieren von Objekten zwischen Client und Server:.NET Remoting supports two ways to serialize and deserialize objects between the client and server:

  • Als Wert – die Werte des Objekts werden über Ebenengrenzen hinweg serialisiert, und eine neue Instanz dieses Objekts wird auf der anderen Ebene erstellt.By value – the values of the object are serialized across tier boundaries, and a new instance of that object is created on the other tier. Alle Aufrufe von Methoden oder Eigenschaften der neuen Instanz werden ausschließlich lokal ausgeführt und wirken sich nicht auf das ursprüngliche Objekt oder die ursprüngliche Ebene aus.Any calls to methods or properties of that new instance execute only locally and do not affect the original object or tier.

  • Verweisübergabe – ein spezieller "Objektverweis" über Ebenengrenzen hinweg serialisiert wird.By reference – a special "object reference" is serialized across tier boundaries. Wenn eine Ebene mit Methoden oder Eigenschaften des Objekts interagiert, erfolgt die Kommunikation zurück an das ursprüngliche Objekt oder die ursprüngliche Ebene.When one tier interacts with methods or properties of that object, it communicates back to the original object on the original tier. Als-Verweis-Objekte können in beide Richtungen übertragen werden – vom Server an den Client oder vom Client an den Server.By-reference objects can flow in either direction – server to client, or client to server.

Als-Wert-Typen werden in Remoting mit dem [Serializable]-Attribut gekennzeichnet oder implementieren "ISerializable", wie im folgenden Beispiel gezeigt:By-value types in Remoting are marked with the [Serializable] attribute or implement ISerializable, like in the following example:

[Serializable]  
public class RemotingCustomer  
{  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public int CustomerId { get; set; }  
}  

Als Verweis-Typen werden von der MarshalByRefObject-Klasse abgeleitet, wie im folgenden Beispiel gezeigt:By-reference types derive from the MarshalByRefObject class, like in the following example:

public class RemotingCustomerReference : MarshalByRefObject  
{  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public int CustomerId { get; set; }  
}  

Es ist äußerst wichtig, die Auswirkung von Verweisobjekten in Remoting zu verstehen.It is extremely important to understand the implications of Remoting’s by-reference objects. Wenn eine der beiden Ebenen (Client oder Server) ein Verweisobjekt an die andere Ebene sendet, werden alle Methodenaufrufe auf der Ebene ausgeführt, zu der das Objekt gehört.If either tier (client or server) sends a by-reference object to the other tier, all method calls execute back on the tier owning the object. Beispiel: Wenn ein Client Methoden für ein vom Server zurückgegebenes Verweisobjekt aufruft, führt dies zur Ausführung von Code auf dem Server.For example, a client calling methods on a by-reference object returned by the server will execute code on the server. Auf ähnliche Weise wird beim Aufruf von durch den Client bereitgestellten Verweisobjekten durch den Server Code auf dem Client ausgeführt.Similarly, a server calling methods on a by-reference object provided by the client will execute code back on the client. Aus diesem Grund empfiehlt sich die Verwendung von .NET Remoting nur in vollständig vertrauenswürdigen Umgebungen.For this reason, the use of .NET Remoting is recommended only within fully-trusted environments. Das Offenlegen eines öffentlichen .NET Remoting-Endpunkts für nicht vertrauenswürdige Clients macht einen Remoting-Server anfällig für Angriffe.Exposing a public .NET Remoting endpoint to untrusted clients will make a Remoting server vulnerable to attack.

Serialisierung in WCFSerialization in WCF

WCF unterstützt nur die Serialisierung nach Wert.WCF supports only by-value serialization. Die gängigste Methode zum Definieren eines Typs für den Austausch zwischen Client und Server wird im folgenden Beispiel gezeigt:The most common way to define a type to exchange between client and server is like in the following example:

[DataContract]  
public class WCFCustomer  
{  
    [DataMember]  
    public string FirstName { get; set; }  

    [DataMember]  
    public string LastName { get; set; }  

    [DataMember]  
    public int CustomerId { get; set; }  
}  

Das [DataContract]-Attribut gibt an, dass dieser Typ zwischen Client und Server serialisiert und deserialisiert werden kann.The [DataContract] attribute identifies this type as one that can be serialized and deserialized between client and server. Das Attribut [DataMember] identifiziert die einzelnen Eigenschaften oder Felder für die Serialisierung.The [DataMember] attribute identifies the individual properties or fields to serialize.

Wenn WCF ein Objekt über Ebenen hinweg sendet, werden nur die Werte serialisiert, und es wird eine neue Instanz des Objekts auf der anderen Ebene erstellt.When WCF sends an object across tiers, it serializes only the values and creates a new instance of the object on the other tier. Sämtliche Interaktionen mit den Werten des Objekts erfolgen nur lokal – es findet im Gegensatz zu den Als-Verweis-Objekten in .NET Remoting keine Kommunikation mit der anderen Ebene statt.Any interactions with the values of the object occur only locally – they do not communicate with the other tier the way .NET Remoting by-reference objects do. Weitere Informationen finden Sie unter den folgenden Themen:For more information, see the following topics:

Funktionen für die AusnahmebehandlungException Handling Capabilities

Ausnahmen in .NET RemotingExceptions in .NET Remoting

Von einem Remoting-Server ausgelöste Ausnahmen werden serialisiert, an den Client gesendet und lokal auf dem Client wie jede andere Ausnahme ausgelöst.Exceptions thrown by a Remoting server are serialized, sent to the client, and thrown locally on the client like any other exception. Benutzerdefinierte Ausnahmen können durch das Erstellen einer Unterklasse für den Ausnahmetyp und Markierung mit [Serializable] erstellt werden.Custom exceptions can be created by sub-classing the Exception type and marking it with [Serializable]. Die meisten Framework-Ausnahmen sind bereits in dieser Weise markiert. Deshalb können die meisten von ihnen durch den Server ausgelöst, serialisiert und erneut auf dem Client ausgelöst werden.Most framework exceptions are already marked in this way, allowing most to be thrown by the server, serialized, and re-thrown on the client. Wenngleich dieses Design bei der Entwicklung praktisch ist, werden so möglicherweise unbeabsichtigt Informationen gegenüber dem Client offengelegt.Though this design is convenient during development, server-side information can inadvertently be disclosed to the client. Dies ist einer der vielen Gründe, aus denen Remoting nur in vollständig vertrauenswürdigen Umgebungen eingesetzt werden sollte.This is one of many reasons Remoting should be used only in fully-trusted environments.

Ausnahmen und Fehler in WCFExceptions and Faults in WCF

WCF lässt keine Rückgabe zufälliger Ausnahmetypen vom Server an den Client zu, da dies zu einer unbeabsichtigten Offenlegung von Informationen führen kann.WCF does not allow arbitrary exception types to be returned from the server to the client because it could lead to inadvertent information disclosure. Wenn ein Dienstvorgang eine unerwartete Ausnahme ausgelöst wird, führt dies dazu, dass auf dem Client eine allgemeine FaultException ausgelöst wird.If a service operation throws an unexpected exception, it causes a general purpose FaultException to be thrown on the client. Diese Ausnahme enthält keinerlei Informationen dazu, warum oder wo das Problem aufgetreten ist, und für einige Anwendungen reicht dies aus.This exception does not carry any information why or where the problem occurred, and for some applications this is sufficient. Anwendungen, die ausführlichere Fehlerinformationen an den Client kommunizieren müssen, definieren zu diesem Zweck einen Fehlervertrag.Applications that need to communicate richer error information to the client do this by defining a fault contract.

Hierzu erstellen Sie zunächst einen [DataContract]-Typ, der die Fehlerinformationen enthält.To do this, first create a [DataContract] type to carry the fault information.

[DataContract]  
public class CustomerServiceFault  
{  
    [DataMember]  
    public string ErrorMessage { get; set; }  

    [DataMember]  
    public int CustomerId {get;set;}  
}  

Geben Sie den Fehlervertrag an, der für jeden Dienstvorgang zu verwenden ist.Specify the fault contract to use for each service operation.

[ServiceContract]  
public interface IWCFServer  
{  
    [OperationContract]  
    [FaultContract(typeof(CustomerServiceFault))]  
    Customer GetCustomer(int customerId);  
}  

Der Server meldet Fehlerbedingungen durch das Auslösen einer FaultException.The server reports error conditions by throwing a FaultException.

throw new FaultException<CustomerServiceFault>(  
    new CustomerServiceFault() {   
        CustomerId = customerId,   
        ErrorMessage = "Illegal customer Id"   
    });  

Und wenn der Client eine Anforderung an den Server sendet, können Fehler als normale Ausnahmen abgefangen werden.And whenever the client makes a request to the server, it can catch faults as normal exceptions.

try  
{  
    Customer customer = server.GetCustomer(-1);  
}  
catch (FaultException<CustomerServiceFault> fault)  
{  
    Console.WriteLine(String.Format("Fault received: {0}",  
    fault.Detail.ErrorMessage));  
}  

Weitere Informationen zu Fehlerverträgen finden Sie unter FaultException.For more information about fault contracts, see FaultException.

SicherheitsüberlegungenSecurity Considerations

Sicherheit in .NET RemotingSecurity in .NET Remoting

Einige .NET Remoting-Kanäle unterstützen Sicherheitsfunktionen wie beispielsweise Authentifizierung und Verschlüsselung auf Kanalebene (IPC und TCP).Some .NET Remoting channels support security features such as authentication and encryption at the channel layer (IPC and TCP). Der HTTP-Kanal nutzt sowohl für die Authentifizierung als auch für die Verschlüsselung Internetinformationsdienste (IIS).The HTTP channel relies on Internet Information Services (IIS) for both authentication and encryption. Trotz dieser Unterstützung sollten Sie .NET Remoting als unsicheres Kommunikationsprotokoll betrachten und nur in vollständig vertrauenswürdigen Umgebungen einsetzen.Despite this support, you should consider .NET Remoting an unsecure communication protocol and use it only within fully-trusted environments. Machen Sie niemals einen öffentlichen Remoting-Endpunkt für das Internet oder nicht vertrauenswürdige Clients verfügbar.Never expose a public Remoting endpoint to the Internet or untrusted clients.

Sicherheit in WCFSecurity in WCF

WCF wurde unter dem Gesichtspunkt der Sicherheit entworfen, teilweise auch deshalb, um die Schwachstellen in .NET Remoting zu beheben.WCF was designed with security in mind, in part to address the kinds of vulnerabilities found in .NET Remoting. WCF bietet Sicherheit auf Transport- und Nachrichtenebene und bietet zahlreiche Optionen für Authentifizierung, Autorisierung, Verschlüsselung usw.WCF offers security at both the transport and message level, and offers many options for authentication, authorization, encryption, and so on. Weitere Informationen finden Sie unter den folgenden Themen:For more information, see the following topics:

Migration nach WCFMigrating to WCF

Welche Vorteile bietet die Migration von Remoting nach WCF?Why Migrate from Remoting to WCF?

  • .NET Remoting ist ein älteres Produkt handelt..NET Remoting is a legacy product. Wie in beschrieben .NET Remoting, es wird ein legacy-Produkt betrachtet und wird für neue Entwicklungen nicht empfohlen.As described in .NET Remoting, it is considered a legacy product and is not recommended for new development. Für neue und vorhandene Anwendungen wird der Einsatz von WCF oder ASP.NET-Web-API empfohlen.WCF or ASP.NET Web API are recommended for new and existing applications.

  • WCF verwendet plattformübergreifende Standards.WCF uses cross-platform standards. WCF wurde unter dem Gesichtspunkt einer plattformübergreifenden Interoperabilität entwickelt und unterstützt zahlreiche Industriestandards (SOAP, WS-Security, WS-Trust, usw.).WCF was designed with cross-platform interoperability in mind and supports many industry standards (SOAP, WS-Security, WS-Trust, etc.). Ein WCF-Dienst kann mit Clients interagieren, auf denen andere Betriebssysteme als Windows ausgeführt werden.A WCF service can interoperate with clients running on operating systems other than Windows. Remoting wurde in erster Linie für Umgebungen entwickelt, in denen sowohl die Server- als auch die Clientanwendungen mithilfe von .NET Framework auf einem Windows-Betriebssystem ausgeführt werden.Remoting was designed primarily for environments where both the server and client applications run using the .NET framework on a Windows operating system.

  • WCF bietet integrierte Sicherheit.WCF has built-in security. WCF wurde unter Berücksichtigung von Sicherheitsaspekten entworfen und bietet viele Optionen für die Authentifizierung, die Sicherheit auf Transport- und Nachrichtenebene usw. Remoting wurde entworfen, um die Interoperabilität von Anwendungen zu vereinfachen, die Sicherheit in nicht vertrauenswürdigen Umgebungen ist jedoch nicht gewährleistet.WCF was designed with security in mind and offers many options for authentication, transport level security, message level security, etc. Remoting was designed to make it easy for applications to interoperate but was not designed to be secure in non-trusted environments. WCF wurde entworfen, um sowohl in vertrauenswürdigen als auch in nicht vertrauenswürdigen Umgebungen eingesetzt zu werden.WCF was designed to work in both trusted and non-trusted environments.

Empfehlungen für die MigrationMigration Recommendations

Für die Migration von .NET Remoting nach WCF werden die folgenden Schritte empfohlen:The following are the recommended steps to migrate from .NET Remoting to WCF:

  • Erstellen Sie den Dienstvertrag.Create the service contract. Definieren Sie Ihre Dienstschnittstellentypen, und markieren Sie diese mit dem [ServiceContract]-Attribut. Markieren Sie alle Methoden, die der Client mit [OperationContract] aufrufen darf.Define your service interface types, and mark them with the [ServiceContract] attribute.Mark all the methods the clients will be allowed to call with [OperationContract].

  • Erstellen des Datenvertrags an.Create the data contract. Definieren Sie die Datentypen, die zwischen Server und Client ausgetauscht werden, und markieren Sie diese mit dem Attribut [DataContract].Define the data types that will be exchanged between server and client, and mark them with the [DataContract] attribute. Markieren Sie alle Felder und Eigenschaften, die der Client mit [DataMember] verwenden darf.Mark all the fields and properties the client will be allowed to use with [DataMember].

  • Erstellen des fehlervertrags (optional).Create the fault contract (optional). Erstellen Sie die Typen, die zwischen Server und Client ausgetauscht werden, wenn Fehler auftreten.Create the types that will be exchanged between server and client when errors are encountered. Markieren Sie diese Typen mit [DataContract] und [DataMember], um sie serialisierbar zu machen.Mark these types with [DataContract] and [DataMember] to make them serializable. Markieren Sie alle Dienstvorgänge, die Sie mit [OperationContract] markiert haben, auch mit [FaultContract], um die Fehler festzulegen, die zurückgegeben werden können.For all service operations you marked with [OperationContract], also mark them with [FaultContract] to indicate which errors they may return.

  • Konfigurieren Sie und hosten Sie des Diensts.Configure and host the service. Sobald der Dienstvertrag erstellt wurde, besteht der nächste Schritt darin, eine Bindung zu konfigurieren, die für den Dienst an einem Endpunkt verfügbar gemacht wird.Once the service contract has been created, the next step is to configure a binding to expose the service at an endpoint. Weitere Informationen finden Sie unter Endpunkte: Adressen, Bindungen und Verträge.For more information, see Endpoints: Addresses, Bindings, and Contracts.

Nach der Migration einer Remoting-Anwendung nach WCF ist es wichtig, Abhängigkeiten mit .NET Remoting zu entfernen.Once a Remoting application has been migrated to WCF, it is still important to remove dependencies on .NET Remoting. Auf diese Weise wird sichergestellt, dass alle Remoing-Sicherheitsanfälligkeiten aus der Anwendung entfernt werden.This ensures that any Remoting vulnerabilities are removed from the application. Folgende Schritte müssen ausgeführt werden:These steps include the following:

  • Beenden Sie die Verwendung von "MarshalByRefObject".Discontinue use of MarshalByRefObject. Der MarshalByRefObject-Typ ist nur in Remoting vorhanden und wird von WCF nicht verwendet.The MarshalByRefObject type exists only for Remoting and is not used by WCF. Alle Anwendungstypen, die Unterklassen von MarshalByRefObject verwenden, sollten entfernt oder geändert werden.Any application types that sub-class MarshalByRefObject should be removed or changed. Der MarshalByRefObject-Typ ist nur in Remoting vorhanden und wird von WCF nicht verwendet.The MarshalByRefObject type exists only for Remoting and is not used by WCF. Alle Anwendungstypen, die Unterklassen von MarshalByRefObject verwenden, sollten entfernt oder geändert werden.Any application types that sub-class MarshalByRefObject should be removed or changed.

  • Beenden Sie die Verwendung von [Serializable] und ISerializable.Discontinue use of [Serializable] and ISerializable. Das [Serializable]-Attribut und die ISerializable-Schnittstelle wurden ursprünglich zum Serialisieren von Typen in vertrauenswürdigen Umgebungen entworfen und werden von Remoting verwendet.The [Serializable] attribute and ISerializable interface were originally designed to serialize types within trusted environments, and they are used by Remoting. Die WCF-Serialisierung beruht auf Typen, die mit [DataContract] und [DataMember] markiert sind.WCF serialization relies on types being marked with [DataContract] and [DataMember]. Die von einer Anwendung verwendeten Datentypen sollten geändert werden, um [DataContract] zu verwenden und nicht ISerializable oder [Serializable].Data types used by an application should be modified to use [DataContract] and not to use ISerializable or [Serializable]. Das [Serializable]-Attribut und die ISerializable-Schnittstelle wurden ursprünglich zum Serialisieren von Typen in vertrauenswürdigen Umgebungen entworfen und werden von Remoting verwendet.The [Serializable] attribute and ISerializable interface were originally designed to serialize types within trusted environments, and they are used by Remoting. Die WCF-Serialisierung beruht auf Typen, die mit [DataContract] und [DataMember] markiert sind.WCF serialization relies on types being marked with [DataContract] and [DataMember]. Die von einer Anwendung verwendeten Datentypen sollten geändert werden, um [DataContract] zu verwenden und nicht ISerializable oder [Serializable].Data types used by an application should be modified to use [DataContract] and not to use ISerializable or [Serializable].

MigrationsszenarienMigration Scenarios

Betrachten wir nun, wie die folgenden gängigen Remoting-Szenarien in WCF realisiert werden:Now let’s see how to accomplish the following common Remoting scenarios in WCF:

  1. Server gibt ein Objekt als Wert an den Client zurückServer returns an object by-value to the client

  2. Server gibt ein Objekt als Verweis an den Client zurückServer returns an object by-reference to the client

  3. Client sendet ein Objekt als Wert an den ServerClient sends an object by-value to the server

Hinweis

Das Senden eines Objekts als Verweis vom Client an den Server ist in WCF nicht zulässig.Sending an object by-reference from the client to the server is not allowed in WCF.

Nehmen Sie beim Durcharbeiten dieser Szenarien an, dass die Baseline-Schnittstellen für .NET Remoting wie im folgenden Beispiel aussehen.When reading through these scenarios, assume our baseline interfaces for .NET Remoting look like the following example. Die .NET Remoting-Implementierung ist hier nicht wichtig, da nur dargestellt werden soll, wie WCF zur Implementierung einer äquivalenten Funktionalität genutzt wird.The .NET Remoting implementation is not important here because we want to illustrate only how to use WCF to implement equivalent functionality.

public class RemotingServer : MarshalByRefObject  
{  
    // Demonstrates server returning object by-value  
    public Customer GetCustomer(int customerId) {…}  

    // Demonstrates server returning object by-reference  
    public CustomerReference GetCustomerReference(int customerId) {…}  

    // Demonstrates client passing object to server by-value  
    public bool UpdateCustomer(Customer customer) {…}  
}  

Szenario 1: Der Dienst gibt ein Objekt per Wert zurückScenario 1: Service Returns an Object by Value

In diesem Szenario wird gezeigt, wie ein Server ein Objekt per Wert an den Client zurückgibt.This scenario demonstrates a server returning an object to the client by value. WCF gibt Objekte immer per Wert an den Server zurück, daher beschreiben die folgenden Schritte lediglich, wie ein normaler WCF-Dienst erstellt wird.WCF always returns objects from the server by value, so the following steps simply describe how to build a normal WCF service.

  1. Zuerst definieren Sie eine öffentliche Schnittstelle für den WCF-Dienst und markieren ihn mit dem [ServiceContract]-Attribut.Start by defining a public interface for the WCF service and mark it with the [ServiceContract] attribute. [OperationContract] wird verwendet, um die serverseitigen Methoden zu identifizieren, die der Client aufruft.We use [OperationContract] to identify the server-side methods our client will call.
[ServiceContract]  
public interface ICustomerService  
{  
    [OperationContract]  
    Customer GetCustomer(int customerId);  

    [OperationContract]  
    bool UpdateCustomer(Customer customer);  
}  
  1. Im nächsten Schritt wird der Datenvertrag für diesen Dienst erstellt.The next step is to create the data contract for this service. Dazu werden Klassen (keine Schnittstellen) erstellt, die mit dem [DataContract]-Attribut markiert werden.We do this by creating classes (not interfaces) marked with the [DataContract] attribute. Die einzelnen Eigenschaften oder Felder, die für Client und Server sichtbar sein sollen, werden mit [DataMember] markiert.The individual properties or fields we want visible to both client and server are marked with [DataMember]. Wenn abgeleitete Typen zulässig sein sollen, müssen diese mit dem [KnownType]-Attribut identifiziert werden.If we want derived types to be allowed, we must use the [KnownType] attribute to identify them. Die einzigen Typen, für die WCF eine Serialisierung oder Deserialisierung zulässt, sind die in der Dienstschnittstelle enthaltenen Typen sowie diese "bekannten Typen".The only types WCF will allow to be serialized or deserialized for this service are those in the service interface and these "known types". Jeder Versuch, andere als in dieser Liste enthaltene Typen zu verwenden, wird zurückgewiesen.Attempting to exchange any other type not in this list will be rejected.
[DataContract]  
[KnownType(typeof(PremiumCustomer))]  
public class Customer  
{  
    [DataMember]  
    public string FirstName { get; set; }  

    [DataMember]  
    public string LastName { get; set; }  

    [DataMember]  
    public int CustomerId { get; set; }  
}  

[DataContract]  
public class PremiumCustomer : Customer   
{  
    [DataMember]  
    public int AccountId { get; set; }  
}  
  1. Als Nächstes stellen wir die Implementierung für die Dienstschnittstelle bereit.Next, we provide the implementation for the service interface.
public class CustomerService : ICustomerService  
{  
    public Customer GetCustomer(int customerId)  
    {  
        // read from database  
    }  

    public bool UpdateCustomer(Customer customer)  
    {  
        // write to database  
    }  
}  
  1. Um den WCF-Dienst auszuführen, müssen Sie einen Endpunkt deklarieren, der diese Dienstschnittstelle an einer bestimmten URL über eine bestimmte WCF-Bindung verfügbar macht.To run the WCF service, we need to declare an endpoint that exposes that service interface at a specific URL using a specific WCF binding. Dies wird üblicherweise erreicht, indem die folgenden Abschnitte in die web.config-Datei des Serverprojekts eingefügt werden.This is typically done by adding the following sections to the server project’s web.config file.

    <configuration>  
      <system.serviceModel>  
        <services>  
          <service name="Server.CustomerService">  
            <endpoint address="http://localhost:8083/CustomerService"  
                      binding="basicHttpBinding"  
                      contract="Shared.ICustomerService" />  
          </service>  
        </services>  
      </system.serviceModel>  
    </configuration>  
    
  2. Der WCF-Dienst kann anschließend mit dem folgenden Code gestartet werden:The WCF service can then be started with the following code:

ServiceHost customerServiceHost = new ServiceHost(typeof(CustomerService));  
    customerServiceHost.Open();  
 <span data-ttu-id="e2c5f-300">Wird dieser ServiceHost gestartet, ermittelt er mithilfe der web.config-Datei den richtigen Vertrag sowie die Bindung und den Endpunkt.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-300">When this ServiceHost is started, it uses the web.config file to establish the proper contract, binding and endpoint.</span></span> <span data-ttu-id="e2c5f-301">Weitere Informationen zu Konfigurationsdateien finden Sie unter [Konfigurieren von Diensten mithilfe von Konfigurationsdateien](./configuring-services-using-configuration-files.md).</span><span class="sxs-lookup"><span data-stu-id="e2c5f-301">For more information about configuration files, see [Configuring Services Using Configuration Files](./configuring-services-using-configuration-files.md).</span></span> <span data-ttu-id="e2c5f-302">Diese Art des Serverstarts wird als Selbsthosting bezeichnet.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-302">This style of starting the server is known as self-hosting.</span></span> <span data-ttu-id="e2c5f-303">Weitere Informationen zu anderen Optionen zum Hosten von WCF-Diensten finden Sie unter [Hostingdienste](./hosting-services.md).</span><span class="sxs-lookup"><span data-stu-id="e2c5f-303">To learn more about other choices for hosting WCF services, see [Hosting Services](./hosting-services.md).</span></span>  
  1. Die Datei „app.config“ des Clientprojekts muss übereinstimmende Bindungsinformationen für den Dienstendpunkt deklarieren.The client project’s app.config must declare matching binding information for the service’s endpoint. Die einfachste Möglichkeit hierzu in Visual Studio ist die Verwendung Hinzufügen eines Dienstverweises, die die Datei "App.config" automatisch aktualisiert.The easiest way to do this in Visual Studio is to use Add Service Reference, which will automatically update the app.config file. Alternativ können dieselben Änderungen manuell hinzugefügt werden.Alternatively, these same changes can be added manually.

    <configuration>  
      <system.serviceModel>  
        <client>  
          <endpoint name="customerservice"  
                    address="http://localhost:8083/CustomerService"  
                    binding="basicHttpBinding"  
                    contract="Shared.ICustomerService"/>  
        </client>  
      </system.serviceModel>  
    </configuration>  
    

    Weitere Informationen zur Verwendung von Hinzufügen eines Dienstverweises, finden Sie unter wie: hinzufügen, aktualisieren oder Entfernen eines Dienstverweises.For more information about using Add Service Reference, see How to: Add, Update, or Remove a Service Reference.

  2. Jetzt können wir den WCF-Dienst vom Client aufrufen.Now we can call the WCF service from the client. Dazu erstellen wir eine Kanalfactory für diesen Dienst, fordern einen Kanal an und rufen direkt die gewünschte Methode im Kanal auf.We do this by creating a channel factory for that service, asking it for a channel, and directly calling the method we want on that channel. Dies ist möglich, da der Kanal die Dienstschnittstelle implementiert und die zugrunde liegende Logik für Anforderungen/Antworten verwaltet.We can do this because the channel implements the service’s interface and handles the underlying request/reply logic for us. Der Rückgabewert für diesen Methodenaufruf ist die deserialisierte Kopie der Serverantwort.The return value from that method call is the deserialized copy of the server’s response.

ChannelFactory<ICustomerService> factory =  
    new ChannelFactory<ICustomerService>("customerservice");  
ICustomerService service = factory.CreateChannel();  
Customer customer = service.GetCustomer(42);  
Console.WriteLine(String.Format("  Customer {0} {1} received.",  
        customer.FirstName, customer.LastName));  

WCF gibt Objekte vom Server an den Client immer als Wert zurück.Objects returned by WCF from the server to the client are always by value. Die Objekte sind deserialisierte Kopien der Daten, die vom Server gesendet wurden.The objects are deserialized copies of the data sent by the server. Der Client kann Methoden für diese lokalen Kopien aufrufen, ohne Gefahr zu laufen, durch Rückruffunktionen Servercode aufzurufen.The client can call methods on these local copies without any danger of invoking server code through callbacks.

Szenario 2: Server gibt ein Objekt als Verweis zurückScenario 2: Server Returns an Object By Reference

Dieses Szenario zeigt, wie der Server ein Objekt als Verweis an den Client zurückgibt.This scenario demonstrates the server providing an object to the client by reference. In .NET Remoting erfolgt dies für jeden von "MarshalByRefObject" abgeleiteten Typ automatisch, da diese als Verweis serialisiert werden.In .NET Remoting, this is handled automatically for any type derived from MarshalByRefObject, which is serialized by-reference. Ein Beispiel für dieses Szenario besteht darin, mehreren Clients zu gestatten, unabhängige, sitzungsbasierte, serverseitige Objekte zu verwalten.An example of this scenario is allowing multiple clients to have independent sessionful server-side objects. Wie bereits erwähnt, gibt der WCF-Dienst Objekte immer als Wert zurück, es gibt also keine direkte Entsprechung für ein Per-Verweis-Objekt. Es ist aber möglich, durch eine Verweissemantik mit Verwendung eines EndpointAddress10-Objekts etwas ähnliches zu erreichen.As previously mentioned, objects returned by a WCF service are always by value, so there is no direct equivalent of a by-reference object, but it is possible to achieve something similar to by-reference semantics using an EndpointAddress10 object. Es handelt sich um ein serialisierbares Per-Wert-Objekt, das vom Client dazu verwendet werden kann, ein sitzungsbasiertes Per-Verweis-Objekt auf dem Server abzurufen.This is a serializable by-value object that can be used by the client to obtain a sessionful by-reference object on the server. Dadurch wird das Szenario ermöglicht, über mehrere Clients mit unabhängigen, sitzungsbasierten, serverseitigen Objekten zu verfügen.This enables the scenario of having multiple clients with independent sessionful server-side objects.

  1. Zunächst muss ein WCF-Dienstvertrag definiert werden, der dem sitzungsbasierten Objekt selbst entspricht.First, we need to define a WCF service contract that corresponds to the sessionful object itself.
[ServiceContract(SessionMode = SessionMode.Allowed)]  
    public interface ISessionBoundObject  
    {  
        [OperationContract]  
        string GetCurrentValue();  

        [OperationContract]  
        void SetCurrentValue(string value);  
    }  
> [!TIP]
>  <span data-ttu-id="e2c5f-323">Beachten Sie, dass das sitzungsbasierte Objekt mit [ServiceContract] markiert ist, es handelt sich also um eine normale WCF-Dienstschnittstelle.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-323">Notice that the sessionful object is marked with [ServiceContract], making it a normal WCF service interface.</span></span> <span data-ttu-id="e2c5f-324">Durch Festlegen der SessionMode-Eigenschaft wird angegeben, dass es sich um einen sitzungsbasierten Dienst handelt.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-324">Setting the SessionMode property indicates it will be a sessionful service.</span></span> <span data-ttu-id="e2c5f-325">In WCF bietet eine Sitzung die Möglichkeit, zwischen zwei Endpunkten gesendete Nachrichten zu korrelieren.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-325">In WCF, a session is a way of correlating multiple messages sent between two endpoints.</span></span> <span data-ttu-id="e2c5f-326">Dies bedeutet, dass zwischen dem Client und dem Server eine Sitzung eingerichtet wird, sobald der Client eine Verbindung mit diesem Dienst hergestellt hat.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-326">This means that once a client obtains a connection to this service, a session will be established between the client and the server.</span></span> <span data-ttu-id="e2c5f-327">Der Client verwendet eine einzelne eindeutige Instanz des serverseitigen Objekts für alle Interaktionen innerhalb dieser einzelnen Sitzung.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-327">The client will use a single unique instance of the server-side object for all its interactions within this single session.</span></span>  
  1. Als Nächstes muss die Implementierung dieser Schnittstelle bereitgestellt werden.Next, we need to provide the implementation of this service interface. Durch eine Kennzeichnung mit [ServiceBehavior] und Festlegen von InstanceContextMode wird WCF angewiesen, eine eindeutige Instanz dieses Typs für jede Sitzung zu verwenden.By denoting it with [ServiceBehavior] and setting the InstanceContextMode, we tell WCF we want to use a unique instance of this type for an each session.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]  
    public class MySessionBoundObject : ISessionBoundObject  
    {  
        private string _value;  

        public string GetCurrentValue()  
        {  
            return _value;  
        }  

        public void SetCurrentValue(string val)  
        {  
            _value = val;  
        }  

    }  
  1. Nun benötigen wir eine Möglichkeit, eine Instanz dieses sitzungsbasierten Objekts abzurufen.Now we need a way to obtain an instance of this sessionful object. Hierzu erstellen wir eine weitere WCF-Dienstschnittstelle, die ein EndpointAddress10-Objekt zurückgibt.We do this by creating another WCF service interface that returns an EndpointAddress10 object. Dies ist eine serialisierbare Form eines Endpunkts, die vom Server dazu verwendet werden kann, ein sitzungsbasiertes Objekt zu erstellen.This is a serializable form of an endpoint that the client can use to create the sessionful object.
[ServiceContract]  
    public interface ISessionBoundFactory  
    {  
        [OperationContract]  
        EndpointAddress10 GetInstanceAddress();  
    }  
 <span data-ttu-id="e2c5f-333">Und wir implementieren diesen WCF-Dienst:</span><span class="sxs-lookup"><span data-stu-id="e2c5f-333">And we implement this WCF service:</span></span>  
public class SessionBoundFactory : ISessionBoundFactory  
    {  
        public static ChannelFactory<ISessionBoundObject> _factory =   
            new ChannelFactory<ISessionBoundObject>("sessionbound");  

        public SessionBoundFactory()  
        {  
        }  

        public EndpointAddress10 GetInstanceAddress()  
        {  
            IClientChannel channel = (IClientChannel)_factory.CreateChannel();  
            return EndpointAddress10.FromEndpointAddress(channel.RemoteAddress);  
        }  
    }  
 <span data-ttu-id="e2c5f-334">Diese Implementierung verwaltet eine Singleton-Kanalfactory, um sitzungsbasierte Objekte zu erstellen.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-334">This implementation maintains a singleton channel factory to create sessionful objects.</span></span> <span data-ttu-id="e2c5f-335">Beim Aufruf von GetInstanceAddress() werden ein Kanal sowie ein EndpointAddress10-Objekt erstellt, das effektiv auf die diesem Kanal zugeordnete Remoteadresse verweist.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-335">When GetInstanceAddress() is called, it creates a channel and creates an EndpointAddress10 object that effectively points to the remote address associated with this channel.</span></span> <span data-ttu-id="e2c5f-336">EndpointAddress10 ist einfach ein Datentyp, der als Wert an den Client zurückgegeben werden kann.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-336">EndpointAddress10 is simply a data type that can be returned to the client by-value.</span></span>  
  1. Die Konfigurationsdatei des Servers muss durch Ausführen von zwei Schritten geändert werden, wie im folgenden Beispiel gezeigt:We need to modify the server’s configuration file by doing the following two things as shown in the example below:

    1. Deklarieren einer <Client >-Abschnitt, der den Endpunkt für das sitzungsbasierte Objekt beschreibt.Declare a <client> section that describes the endpoint for the sessionful object. Dies ist notwendig, da der Server in diesem Fall auch als Client fungiert.This is necessary because the server also acts as a client in this situation.

    2. Deklarieren Sie Endpunkte für die Factory und das sitzungsbasierte Objekt.Declare endpoints for the factory and sessionful object. Dies ist erforderlich, damit der Client mit den Dienstendpunkten kommunizieren kann, um EndpointAddress10 abzurufen und den sitzungsbasierten Kanal zu erstellen.This is necessary to allow the client to communicate with the service endpoints to acquire the EndpointAddress10 and to create the sessionful channel.

    <configuration>  
      <system.serviceModel>  
         <client>  
          <endpoint name="sessionbound"  
                    address="net.tcp://localhost:8081/SessionBoundObject"  
                    binding="netTcpBinding"  
                    contract="Shared.ISessionBoundObject"/>  
        </client>  
        <services>  
          <service name="Server.CustomerService">  
            <endpoint address="http://localhost:8083/CustomerService"  
                      binding="basicHttpBinding"  
                      contract="Shared.ICustomerService" />  
          </service>  
          <service name="Server.MySessionBoundObject">  
            <endpoint address="net.tcp://localhost:8081/SessionBoundObject"  
                      binding="netTcpBinding"  
                      contract="Shared.ISessionBoundObject" />  
          </service>  
          <service name="Server.SessionBoundFactory">  
            <endpoint address="net.tcp://localhost:8081/SessionBoundFactory"  
                      binding="netTcpBinding"  
                      contract="Shared.ISessionBoundFactory" />  
          </service>  
        </services>  
      </system.serviceModel>  
    </configuration>  
    

    Anschließend können diese Dienste gestartet werden:And then we can start these services:

ServiceHost factoryHost = new ServiceHost(typeof(SessionBoundFactory));  
factoryHost.Open();  

ServiceHost sessionHost = new ServiceHost(typeof(MySessionBoundObject));  
sessionHost.Open();  
  1. Wir konfigurieren den Client, indem dieselben Endpunkte in der zugehörigen app.config-Datei des Projekts deklariert werden.We configure the client by declaring these same endpoints in its project’s app.config file.

    <configuration>  
      <system.serviceModel>  
        <client>  
          <endpoint name="customerservice"  
                    address="http://localhost:8083/CustomerService"  
                    binding="basicHttpBinding"  
                    contract="Shared.ICustomerService"/>  
          <endpoint name="sessionbound"  
                    address="net.tcp://localhost:8081/SessionBoundObject"  
                    binding="netTcpBinding"  
                    contract="Shared.ISessionBoundObject"/>  
          <endpoint name="factory"  
                    address="net.tcp://localhost:8081/SessionBoundFactory"  
                    binding="netTcpBinding"  
                    contract="Shared.ISessionBoundFactory"/>  
        </client>  
      </system.serviceModel>  
    </configuration>  
    
  2. Zum Erstellen und Nutzen dieses sitzungsbasierten Objekts muss der Client die folgenden Schritte ausführen:In order to create and use this sessionful object, the client must do the following steps:

    1. Erstellen eines Kanals zum ISessionBoundFactory-Dienst.Create a channel to the ISessionBoundFactory service.

    2. Verwenden dieses Kanals, um den Dienst zum Abrufen von EndpointAddress10 aufzurufen.Use that channel to invoke that service to obtain an EndpointAddress10.

    3. Verwenden von EndpointAddress10 zum Erstellen eines Kanals für den Abruf eines sitzungsbasierten Objekts.Use the EndpointAddress10 to create a channel to obtain a sessionful object.

    4. Interaktion mit dem sitzungsbasierten Objekt, um zu veranschaulichen, dass auch bei mehreren Aufrufen dieselbe Instanz verwendet wird.Interact with the sessionful object to demonstrate it remains the same instance across multiple calls.

ChannelFactory<ISessionBoundFactory> channelFactory =   
    new ChannelFactory<ISessionBoundFactory>("factory");  
ISessionBoundFactory sessionFactory = channelFactory.CreateChannel();  

EndpointAddress10 address1 = sessionFactory.GetInstanceAddress();  
EndpointAddress10 address2 = sessionFactory.GetInstanceAddress();  

ChannelFactory<ISessionBoundObject> sessionObjectFactory1 =   
    new ChannelFactory<ISessionBoundObject>(new NetTcpBinding(),   
                                            address1.ToEndpointAddress());  
ChannelFactory<ISessionBoundObject> sessionObjectFactory2 =   
    new ChannelFactory<ISessionBoundObject>(new NetTcpBinding(),   
                                            address2.ToEndpointAddress());  

ISessionBoundObject sessionInstance1 = sessionObjectFactory1.CreateChannel();  
ISessionBoundObject sessionInstance2 = sessionObjectFactory2.CreateChannel();  

sessionInstance1.SetCurrentValue("Hello");  
sessionInstance2.SetCurrentValue("World");  

if (sessionInstance1.GetCurrentValue() == "Hello" &&  
    sessionInstance2.GetCurrentValue() == "World")  
{  
    Console.WriteLine("sessionful server object works as expected");  
}  

WCF gibt Objekte immer als Wert zurück. Es ist jedoch möglich, die entsprechende Verweissemantik durch Verwenden von EndpointAddress10 zu unterstützen.WCF always returns objects by value, but it is possible to support the equivalent of by-reference semantics through the use of EndpointAddress10. Dies ermöglicht dem Client, eine sitzungsbasierte WCF-Dienstinstanz anzufordern, um anschließend mit dieser wie mit jedem anderen WCF-Dienst zu interagieren.This permits the client to request a sessionful WCF service instance, after which it can interact with it like any other WCF service.

Szenario 3: Client sendet eine Per-Wert-Instanz an den ServerScenario 3: Client Sends Server a By-Value Instance

Dieses Szenario zeigt, wie der Client eine nicht primitive Objektinstanz als Wert an den Server sendet.This scenario demonstrates the client sending a non-primitive object instance to the server by value. Da WCF Objekte nur als Wert übergibt, veranschaulicht dieses Szenario die normale WCF-Verwendung.Because WCF only sends objects by value, this scenario demonstrates normal WCF usage.

  1. Verwenden Sie den gleichen WCF-Dienst wie in Szenario 1.Use the same WCF Service from Scenario 1.

  2. Verwenden Sie den Client, um ein neues Per-Wert-Objekt (Customer) sowie einen Kanal zur Kommunikation mit dem ICustomerService-Dienst zu erstellen und das Objekt an diesen zu senden.Use the client to create a new by-value object (Customer), create a channel to communicate with the ICustomerService service, and send the object to it.

ChannelFactory<ICustomerService> factory =  
    new ChannelFactory<ICustomerService>("customerservice");  
ICustomerService service = factory.CreateChannel();  
PremiumCustomer customer = new PremiumCustomer {   
FirstName = "Bob",   
LastName = "Jones",   
CustomerId = 43,   
AccountId = 99};  
bool success = service.UpdateCustomer(customer);  
Console.WriteLine(String.Format("  Server returned {0}.", success));  
 <span data-ttu-id="e2c5f-356">Das Customer-Objekt wird serialisiert und an den Dienst gesendet und anschließend in eine neue Kopie dieses Objekts deserialisiert.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-356">The customer object will be serialized, and sent to the server, where it is deserialized into a new copy of that object.</span></span>  

> [!NOTE]
>  <span data-ttu-id="e2c5f-357">Dieser Code zeigt auch das Senden eines abgeleiteten Typs (PremiumCustomer).</span><span class="sxs-lookup"><span data-stu-id="e2c5f-357">This code also illustrates sending a derived type (PremiumCustomer).</span></span> <span data-ttu-id="e2c5f-358">Die Dienstschnittstelle erwartet ein Customer-Objekt, aber das [KnownType]-Attribut für die Customer-Klasse zeigt an, dass auch PremiumCustomer zulässig ist.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-358">The service interface expects a Customer object, but the [KnownType] attribute on the Customer class indicated PremiumCustomer was also allowed.</span></span> <span data-ttu-id="e2c5f-359">WCF lässt keine Serialisierung oder Deserialisierung von anderen Typen über diese Dienstschnittstelle zu.</span><span class="sxs-lookup"><span data-stu-id="e2c5f-359">WCF will fail any attempt to serialize or deserialize any other type through this service interface.</span></span>  

Der normale WCF-Datenaustausch erfolgt per Wert.Normal WCF exchanges of data are by value. Auf diese Weise wird sichergestellt, dass Methodenaufrufe für diese Datenobjekte nur lokal erfolgen – es wird kein Code auf der anderen Ebene aufgerufen.This guarantees that invoking methods on one of these data objects executes only locally – it will not invoke code on the other tier. Während es möglich ist, etwa durch Verweis-Objekte zurückgegeben zu erreichen aus der Server, es ist nicht möglich, ein Client ein Objekt per Verweis übergeben auf dem Server.While it is possible to achieve something like by-reference objects returned from the server, it is not possible for a client to pass a by-reference object to the server. Ist zwischen Client und Server eine Konversation in beide Richtungen erforderlich, kann dies in WCF mit einem Duplexdienst erreicht werden.A scenario that requires a conversation back and forth between client and server can be achieved in WCF using a duplex service. Weitere Informationen finden Sie unter Duplexdienste.For more information, see Duplex Services.

ZusammenfassungSummary

.NET Remoting ist ein Kommunikationsframework, das ausschließlich in vollständig vertrauenswürdigen Umgebungen eingesetzt werden sollte..NET Remoting is a communication framework intended to be used only within fully-trusted environments. Es handelt sich um ein Legacy-Produkt, das nur zur Bereitstellung von Abwärtskompatibilität unterstützt wird.It is a legacy product and supported only for backward compatibility. Es sollte nicht verwendet werden, um neue Anwendungen zu erstellen.It should not be used to build new applications. Im Gegensatz dazu wurde WCF unter Berücksichtigung von Sicherheitsaspekten entworfen und wird für neue und vorhandene Anwendungen empfohlen.Conversely, WCF was designed with security in mind and is recommended for new and existing applications. Microsoft empfiehlt, vorhandene Remoting-Anwendungen zu migrieren, um stattdessen WCF oder die ASP.NET-Web-API zu verwenden.Microsoft recommends that existing Remoting applications be migrated to use WCF or ASP.NET Web API instead.