Migrazione da .NET Remoting a WCFMigrating from .NET Remoting to WCF

In questo articolo viene descritto come eseguire la migrazione di un'applicazione che usa Servizi remoti .NET per l'uso di Windows Communication Foundation (WCF).This article describes how to migrate an application that uses .NET Remoting to use Windows Communication Foundation (WCF). Vengono confrontati concetti simili tra questi prodotti e quindi viene descritto come realizzare diversi scenari comuni di Servizi remoti .NET in WCF.It compares similar concepts between these products and then describes how to accomplish several common Remoting scenarios in WCF.

Servizi remoti .NET è un prodotto legacy supportato solo per la compatibilità con le versioni precedenti..NET Remoting is a legacy product that is supported only for backward compatibility. Non è sicuro in ambienti ad attendibilità mista poiché non è in grado di mantenere livelli di attendibilità distinti tra il client e il server.It is not secure across mixed-trust environments because it cannot maintain the separate trust levels between client and server. Ad esempio, è consigliabile non esporre mai un endpoint Servizi remoti .NET a Internet o a client non attendibili.For example, you should never expose a .NET Remoting endpoint to the Internet or to untrusted clients. Si consiglia di eseguire la migrazione delle applicazioni Servizi remoti .NET esistenti a tecnologie più recenti e sicure.We recommend existing Remoting applications be migrated to newer and more secure technologies. Se la progettazione dell'applicazione usa solo HTTP ed è RESTful, è consigliabile l'API Web ASP.NET.If the application’s design uses only HTTP and is RESTful, we recommend ASP.NET Web API. Per altre informazioni, vedere l'API Web ASP.NET.For more information, see ASP.NET Web API. Se l'applicazione è basata su SOAP o richiede protocolli diversi da HTTP, come ad esempio TCP, è consigliabile WCF.If the application is based on SOAP or requires non-Http protocols such as TCP, we recommend WCF.

Confronto tra Servizi remoti .NET e WCFComparing .NET Remoting to WCF

In questa sezione vengono confrontati i componenti di base di Servizi remoti .NET con gli equivalenti di WCF.This section compares the basic building blocks of .NET Remoting with their WCF equivalents. Questi componenti di base verranno usati in un secondo momento per creare alcuni scenari client-server comuni in WCF. Nella tabella seguente sono riepilogate le principali analogie e differenze tra Servizi remoti .NET e 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.

Servizi remoti .NET.NET Remoting WCFWCF
Tipo di serverServer type Sottoclasse MarshalByRefObjectSubclass MarshalByRefObject Contrassegno con l'attributo [ServiceContract]Mark with [ServiceContract] attribute
Operazioni di servizioService operations Metodi pubblici nel tipo di serverPublic methods on server type Contrassegno con l'attributo [OperationContract]Mark with [OperationContract] attribute
SerializzazioneSerialization ISerializable o [Serializable]ISerializable or [Serializable] DataContractSerializer o XmlSerializerDataContractSerializer or XmlSerializer
Oggetti passatiObjects passed In base al valore o in base al riferimentoBy-value or by-reference Solo in base al valoreBy-value only
Errori/eccezioniErrors/exceptions Qualsiasi eccezione serializzabileAny serializable exception FaultContract<TDetail>FaultContract<TDetail>
Oggetti proxy clientClient proxy objects Proxy trasparenti fortemente tipizzati vengono creati automaticamente da MarshalByRefObjectsStrongly typed transparent proxies are created automatically from MarshalByRefObjects Proxy fortemente tipizzati vengono generati su richiesta usando ChannelFactory<TChannel >Strongly typed proxies are generated on-demand using ChannelFactory<TChannel>
Piattaforma richiestaPlatform required Sia il client che il server devono usare un sistema operativo Microsoft e .NETBoth client and server must use Microsoft OS and .NET MultipiattaformaCross-platform
Formato dei messaggiMessage format PrivatePrivate Standard di settore (SOAP, WS-* e così via)Industry standards (SOAP, WS-*, etc.)

Confronto dell'implementazione serverServer Implementation Comparison

Creazione di un server in Servizi remoti .NETCreating a Server in .NET Remoting

I tipi di server di Servizi remoti .NET devono derivare da MarshalByRefObject e definire i metodi che il client può chiamare, nel modo seguente:.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) { … }  
}  

I metodi pubblici di questo tipo di server diventano il contratto pubblico disponibile per i client.The public methods of this server type become the public contract available to clients. Non vi è alcuna separazione tra l'interfaccia pubblica del server e la relativa implementazione: un solo tipo le gestisce entrambe.There is no separation between the server’s public interface and its implementation – one type handles both.

Dopo aver definito il tipo di server, questo può essere reso disponibile ai client, come nell'esempio seguente: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();  

Esistono diversi modi per rendere disponibile il tipo di Servizi remoti .NET come server, incluso l'uso di file di configurazione.There are many ways to make the Remoting type available as a server, including using configuration files. Questo è solo un esempio.This is just one example.

Creazione di un server in WCFCreating a Server in WCF

Il passaggio equivalente in WCF prevede la creazione di due tipi: il "contratto di servizio" pubblico e l'implementazione concreta.The equivalent step in WCF involves creating two types -- the public "service contract" and the concrete implementation. Il primo viene dichiarato come un'interfaccia contrassegnata con [ServiceContract].The first is declared as an interface marked with [ServiceContract]. I metodi disponibili per i client sono contrassegnati con [OperationContract]:Methods available to clients are marked with [OperationContract]:

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

L'implementazione del server è definita in una classe concreta distinta, come nell'esempio seguente: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) { … }  
}  

Dopo aver definito questi tipi, il server WCF può essere reso disponibile ai client, come nell'esempio seguente: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();  
}  

Nota

Viene usato TCP in entrambi gli esempi per mantenerli quanto più simili possibile.TCP is used in both examples to keep them as similar as possible. Per esempi relativi all'uso di HTTP, fare riferimento alle procedure dettagliate per gli scenari, disponibili più avanti in questo argomento.Refer to the scenario walk-throughs later in this topic for examples using HTTP.

Esistono diversi modi per configurare e ospitare servizi WCF.There are many ways to configure and to host WCF services. Questo è solo un esempio, basato su un approccio "self-hosted".This is just one example, known as "self-hosted". Per altre informazioni, vedere i seguenti argomenti:For more information, see the following topics:

Confronto dell'implementazione clientClient Implementation Comparison

Creazione di un client in Servizi remoti .NETCreating a Client in .NET Remoting

Una volta che è stato reso disponibile un oggetto server Servizi remoti .NET, questo può essere usato dai client, come nell'esempio seguente: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));  

L'istanza RemotingServer restituita da Activator.GetObject() è denominata "proxy trasparente".The RemotingServer instance returned from Activator.GetObject() is known as a "transparent proxy." Implementa l'API pubblica per il tipo RemotingServer sul client, ma tutti i metodi chiamano l'oggetto server in esecuzione in un altro processo o computer.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.

Creazione di un client in WCFCreating a Client in WCF

Il passaggio equivalente in WCF prevede l'uso di una channel factory per creare il proxy in modo esplicito.The equivalent step in WCF involves using a channel factory to create the proxy explicitly. Analogamente a Servizi remoti .NET, l'oggetto proxy può essere usato per richiamare operazioni sul server, come nell'esempio seguente: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));  

In questo esempio viene illustrata la programmazione a livello di canale perché è molto simile all'esempio relativo a Servizi remoti .NET.This example shows programming at the channel level because it is most similar to the Remoting example. È inoltre disponibile il Aggiungi riferimento al servizio approccio in Visual Studio che genera codice per semplificare la programmazione lato client.Also available is the Add Service Reference approach in Visual Studio that generates code to simplify client programming. Per altre informazioni, vedere i seguenti argomenti:For more information, see the following topics:

Uso della serializzazioneSerialization Usage

Sia Servizi remoti .NET che WCF usano la serializzazione per l'invio di oggetti tra il client e il server, ma vi sono tre importanti differenze:Both .NET Remoting and WCF use serialization to send objects between client and server, but they differ in these important ways:

  1. Vengono usati serializzatori e convenzioni differenti per indicare gli elementi da serializzare.They use different serializers and conventions to indicate what to serialize.

  2. Servizi remoti .NET supporta la serializzazione "in base al riferimento", che consente l'accesso a proprietà o metodi su un livello per l'esecuzione di codice su un altro livello, ovvero attraverso i limiti di sicurezza..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. Questa funzionalità espone vulnerabilità di sicurezza e rappresenta uno dei motivi principali per cui gli endpoint Servizi remoti .NET non devono mai essere esposti a client non attendibili.This capability exposes security vulnerabilities and is one of the main reasons why Remoting endpoints should never be exposed to untrusted clients.

  3. La serializzazione usata da Servizi remoti .NET è di tipo opt-out (vengono esclusi in modo esplicito gli elementi da non serializzare), mentre la serializzazione di WCF è di tipo opt-in (vengono contrassegnati in modo esplicito i membri da serializzare).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).

Serializzazione in Servizi remoti .NETSerialization in .NET Remoting

Servizi remoti .NET supporta due modi per serializzare e deserializzare gli oggetti tra client e server:.NET Remoting supports two ways to serialize and deserialize objects between the client and server:

  • Per valore : i valori dell'oggetto vengono serializzati attraverso i limiti del livello e viene creata una nuova istanza dell'oggetto su un altro livello.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. Tutte le chiamate a metodi o proprietà della nuova istanza sono in esecuzione solo in locale e non influiscono sull'oggetto o sul livello originale.Any calls to methods or properties of that new instance execute only locally and do not affect the original object or tier.

  • Per riferimento – una speciale "riferimento all'oggetto" viene serializzata attraverso i limiti del livello.By reference – a special "object reference" is serialized across tier boundaries. Quando un livello interagisce con metodi o proprietà di tale oggetto, comunica con l'oggetto originale nel livello originale.When one tier interacts with methods or properties of that object, it communicates back to the original object on the original tier. Il flusso degli oggetti in base al riferimento può avvenire in entrambe le direzioni: dal server al client o dal client al server.By-reference objects can flow in either direction – server to client, or client to server.

I tipi in base al valore in Servizi remoti .NET sono contrassegnati con l'attributo [Serializable] o implementano ISerializable, come nell'esempio seguente: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; }  
}  

I tipi in base al riferimento derivano dalla classe MarshalByRefObject, come nell'esempio seguente: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; }  
}  

È estremamente importante comprendere le implicazioni degli oggetti in base al riferimento di Servizi remoti .NET.It is extremely important to understand the implications of Remoting’s by-reference objects. Se un livello (client o server) invia un oggetto in base al riferimento all'altro livello, tutte le chiamate di metodi vengono eseguite nel livello proprietario dell'oggetto.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. Ad esempio, un client che esegue la chiamata di metodi su un oggetto in base al riferimento restituito dal server eseguirà il codice sul server.For example, a client calling methods on a by-reference object returned by the server will execute code on the server. Analogamente, un server che esegue la chiamata di metodi su un oggetto in base al riferimento fornito dal client eseguirà il codice sul client.Similarly, a server calling methods on a by-reference object provided by the client will execute code back on the client. Per questo motivo, l'uso di Servizi remoti .NET è consigliabile solo all'interno di ambienti completamente attendibili.For this reason, the use of .NET Remoting is recommended only within fully-trusted environments. L'esposizione di un endpoint Servizi remoti .NET pubblico a client non attendibili renderà vulnerabile agli attacchi un server Servizi remoti .NET.Exposing a public .NET Remoting endpoint to untrusted clients will make a Remoting server vulnerable to attack.

Serializzazione in WCFSerialization in WCF

WCF supporta solo la serializzazione in base al valore.WCF supports only by-value serialization. Il modo più comune per definire un tipo per lo scambio tra client e server è simile a quello riportato nell'esempio seguente: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; }  
}  

L'attributo [DataContract] identifica questo tipo come serializzabile e deserializzabile tra client e server.The [DataContract] attribute identifies this type as one that can be serialized and deserialized between client and server. L'attributo [DataMember] identifica le singole proprietà o i singoli campi da serializzare.The [DataMember] attribute identifies the individual properties or fields to serialize.

Quando WCF invia un oggetto tra i livelli, serializza solo i valori e crea una nuova istanza dell'oggetto nell'altro livello.When WCF sends an object across tiers, it serializes only the values and creates a new instance of the object on the other tier. Tutte le interazioni con i valori dell'oggetto avvengono solo in locale: non comunicano con l'altro livello come nel caso degli oggetti in base al riferimento di Servizi remoti .NET.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. Per altre informazioni, vedere i seguenti argomenti:For more information, see the following topics:

Funzionalità di gestione delle eccezioniException Handling Capabilities

Eccezioni in Servizi remoti .NETExceptions in .NET Remoting

Le eccezioni generate da un server Servizi remoti .NET vengono serializzate, inviate al client e generate in locale sul client come qualsiasi altra eccezione.Exceptions thrown by a Remoting server are serialized, sent to the client, and thrown locally on the client like any other exception. È possibile creare eccezioni personalizzate assegnando una sottoclasse al tipo Exception e contrassegnandolo con [Serializable].Custom exceptions can be created by sub-classing the Exception type and marking it with [Serializable]. La maggior parte delle eccezioni del framework sono già contrassegnate in questo modo, pertanto possono essere generate dal server, serializzate e generate nuovamente sul client.Most framework exceptions are already marked in this way, allowing most to be thrown by the server, serialized, and re-thrown on the client. Benché questa progettazione sia utile in fase di sviluppo, è possibile che informazioni sul lato server vengano inavvertitamente rivelate al client.Though this design is convenient during development, server-side information can inadvertently be disclosed to the client. Questo è uno dei diversi motivi per cui Servizi remoti .NET deve essere usato solo in ambienti completamente attendibili.This is one of many reasons Remoting should be used only in fully-trusted environments.

Eccezioni ed errori in WCFExceptions and Faults in WCF

WCF non consente la restituzione di tipi di eccezione arbitrari dal server al client, poiché ciò potrebbe causare la divulgazione accidentale di informazioni.WCF does not allow arbitrary exception types to be returned from the server to the client because it could lead to inadvertent information disclosure. Se un'operazione del servizio genera un'eccezione imprevista, questo determina la generazione di una FaultException generica sul client.If a service operation throws an unexpected exception, it causes a general purpose FaultException to be thrown on the client. Tale eccezione non include informazioni sul motivo del problema o sulla posizione in cui si è verificato e per alcune applicazioni è sufficiente.This exception does not carry any information why or where the problem occurred, and for some applications this is sufficient. Le applicazioni che devono comunicare al client informazioni più dettagliate sugli errori possono eseguire questa operazione definendo un contratto di errore.Applications that need to communicate richer error information to the client do this by defining a fault contract.

A tale scopo, creare innanzitutto un tipo [DataContract] per fornire le informazioni sull'errore.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;}  
}  

Specificare il contratto di errore da usare per ogni operazione del servizio.Specify the fault contract to use for each service operation.

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

Il server segnala le condizioni di errore generando una FaultException.The server reports error conditions by throwing a FaultException.

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

Ogni volta che il client effettua una richiesta al server, può intercettare gli errori come normali eccezioni.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));  
}  

Per altre informazioni sui contratti di errore, vedere FaultException.For more information about fault contracts, see FaultException.

Considerazioni sulla sicurezzaSecurity Considerations

Sicurezza in Servizi remoti .NETSecurity in .NET Remoting

Alcuni canali di Servizi remoti .NET supportano funzionalità di sicurezza quali l'autenticazione e la crittografia a livello di canale (IPC e TCP).Some .NET Remoting channels support security features such as authentication and encryption at the channel layer (IPC and TCP). Il canale HTTP si basa su Internet Information Services (IIS) sia per l'autenticazione che per la crittografia.The HTTP channel relies on Internet Information Services (IIS) for both authentication and encryption. Nonostante questo supporto, è necessario considerare Servizi remoti .NET un protocollo di comunicazione non sicuro e usarlo solo all'interno di ambienti completamente attendibili.Despite this support, you should consider .NET Remoting an unsecure communication protocol and use it only within fully-trusted environments. Non esporre mai un endpoint Servizi remoti .NET pubblico a Internet o a client non attendibili.Never expose a public Remoting endpoint to the Internet or untrusted clients.

Sicurezza in WCFSecurity in WCF

WCF è stato progettato tenendo conto della sicurezza, in parte per risolvere i tipi di vulnerabilità che sono presenti in Servizi remoti .NET.WCF was designed with security in mind, in part to address the kinds of vulnerabilities found in .NET Remoting. WCF garantisce la sicurezza sia a livello di trasporto che di messaggi e offre numerose opzioni per l'autenticazione, l'autorizzazione, la crittografia e così via.WCF offers security at both the transport and message level, and offers many options for authentication, authorization, encryption, and so on. Per altre informazioni, vedere i seguenti argomenti:For more information, see the following topics:

Migrazione a WCFMigrating to WCF

Perché eseguire la migrazione da Servizi remoti .NET a WCF?Why Migrate from Remoting to WCF?

  • Servizi remoti .NET è un prodotto legacy..NET Remoting is a legacy product. Come descritto in .NET Remoting, viene considerato un prodotto legacy e non è consigliato per nuove attività di sviluppo.As described in .NET Remoting, it is considered a legacy product and is not recommended for new development. Per le applicazioni nuove ed esistenti sono consigliati WCF o l'API Web ASP.NET.WCF or ASP.NET Web API are recommended for new and existing applications.

  • WCF Usa standard multipiattaforma.WCF uses cross-platform standards. WCF è stato progettato tenendo conto dell'interoperabilità tra le piattaforme e supporta numerosi standard di settore (SOAP, WS-Security, WS-Trust e così via).WCF was designed with cross-platform interoperability in mind and supports many industry standards (SOAP, WS-Security, WS-Trust, etc.). Un servizio WCF può interagire con client in esecuzione in sistemi operativi diversi da Windows.A WCF service can interoperate with clients running on operating systems other than Windows. Servizi remoti .NET è stato progettato principalmente per gli ambienti in cui sia le applicazioni client che quelle server vengono eseguite tramite .NET Framework in un sistema operativo Windows.Remoting was designed primarily for environments where both the server and client applications run using the .NET framework on a Windows operating system.

  • WCF dispone di sicurezza incorporati.WCF has built-in security. WCF è stato progettato prestando particolare attenzione alla sicurezza e offre numerose opzioni per l'autenticazione, la sicurezza a livello di trasporto, la sicurezza a livello di messaggi e così via. Servizi remoti .NET è stato progettato per semplificare l'interoperabilità tra le applicazioni, ma non per garantire la sicurezza in ambienti non attendibili.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 è stato progettato per l'uso sia in ambienti attendibili che non attendibili.WCF was designed to work in both trusted and non-trusted environments.

Suggerimenti sulla migrazioneMigration Recommendations

Di seguito sono riportate le procedure consigliate per la migrazione da Servizi remoti .NET a WCF:The following are the recommended steps to migrate from .NET Remoting to WCF:

  • Creare il contratto di servizio.Create the service contract. Definire i tipi di interfaccia di servizio e contrassegnarli con l'attributo [ServiceContract]. Contrassegnare tutti i metodi che i client saranno autorizzati a chiamare con [OperationContract].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].

  • Creare il contratto dati.Create the data contract. Definire i tipi di dati che verranno scambiati tra il server e il client e contrassegnarli con l'attributo [DataContract].Define the data types that will be exchanged between server and client, and mark them with the [DataContract] attribute. Contrassegnare tutti i campi e le proprietà che il client sarà autorizzato a usare con [DataMember].Mark all the fields and properties the client will be allowed to use with [DataMember].

  • Creare il contratto di errore (facoltativo).Create the fault contract (optional). Creare i tipi che verranno scambiati tra il server e il client quando si verificano errori.Create the types that will be exchanged between server and client when errors are encountered. Contrassegnare questi tipi con [DataContract] e [DataMember] per renderli serializzabili.Mark these types with [DataContract] and [DataMember] to make them serializable. Contrassegnare inoltre con [FaultContract] tutte le operazioni di servizio contrassegnate con [OperationContract] per indicare quali errori possono restituire.For all service operations you marked with [OperationContract], also mark them with [FaultContract] to indicate which errors they may return.

  • Configurare e ospitare il servizio.Configure and host the service. Dopo aver creato il contratto di servizio, il passaggio successivo consiste nel configurare un'associazione per esporre il servizio in un endpoint.Once the service contract has been created, the next step is to configure a binding to expose the service at an endpoint. Per ulteriori informazioni, vedere endpoint: indirizzi, associazioni e contratti.For more information, see Endpoints: Addresses, Bindings, and Contracts.

Una volta che è stata eseguita la migrazione a WCF di un'applicazione Servizi remoti .NET, è comunque importante rimuovere le dipendenze da Servizi remoti .NET.Once a Remoting application has been migrated to WCF, it is still important to remove dependencies on .NET Remoting. Questo garantisce che eventuali vulnerabilità di Servizi remoti .NET vengano rimosse dall'applicazione.This ensures that any Remoting vulnerabilities are removed from the application. Tali passaggi sono:These steps include the following:

  • Interrompere l'uso di MarshalByRefObject.Discontinue use of MarshalByRefObject. Il tipo MarshalByRefObject esiste solo per Servizi remoti .NET e non viene usato da WCF.The MarshalByRefObject type exists only for Remoting and is not used by WCF. Tutti i tipi di applicazioni che usano la sottoclasse MarshalByRefObject devono essere rimossi o modificati.Any application types that sub-class MarshalByRefObject should be removed or changed. Il tipo MarshalByRefObject esiste solo per Servizi remoti .NET e non viene usato da WCF.The MarshalByRefObject type exists only for Remoting and is not used by WCF. Tutti i tipi di applicazioni che usano la sottoclasse MarshalByRefObject devono essere rimossi o modificati.Any application types that sub-class MarshalByRefObject should be removed or changed.

  • Interrompere l'uso di [Serializable] e ISerializable.Discontinue use of [Serializable] and ISerializable. L'attributo [Serializable] e l'interfaccia ISerializable erano originariamente concepiti per la serializzazione di tipi all'interno di ambienti attendibili e vengono usati da Servizi remoti .NET.The [Serializable] attribute and ISerializable interface were originally designed to serialize types within trusted environments, and they are used by Remoting. La serializzazione di WCF si basa sui tipi contrassegnati con [DataContract] e [DataMember].WCF serialization relies on types being marked with [DataContract] and [DataMember]. I tipi di dati usati da un'applicazione devono essere modificati in modo da usare [DataContract] invece di ISerializable o [Serializable].Data types used by an application should be modified to use [DataContract] and not to use ISerializable or [Serializable]. L'attributo [Serializable] e l'interfaccia ISerializable erano originariamente concepiti per la serializzazione di tipi all'interno di ambienti attendibili e vengono usati da Servizi remoti .NET.The [Serializable] attribute and ISerializable interface were originally designed to serialize types within trusted environments, and they are used by Remoting. La serializzazione di WCF si basa sui tipi contrassegnati con [DataContract] e [DataMember].WCF serialization relies on types being marked with [DataContract] and [DataMember]. I tipi di dati usati da un'applicazione devono essere modificati in modo da usare [DataContract] invece di ISerializable o [Serializable].Data types used by an application should be modified to use [DataContract] and not to use ISerializable or [Serializable].

Scenari di migrazioneMigration Scenarios

Verrà ora descritto come realizzare in WCF i seguenti scenari comuni di Servizi remoti .NET:Now let’s see how to accomplish the following common Remoting scenarios in WCF:

  1. Il server restituisce al client un oggetto in base al valoreServer returns an object by-value to the client

  2. Il server restituisce al client un oggetto in base al riferimentoServer returns an object by-reference to the client

  3. Il client invia al server un oggetto in base al valoreClient sends an object by-value to the server

Nota

L'invio di un oggetto in base al riferimento dal client al server non è consentito in WCF.Sending an object by-reference from the client to the server is not allowed in WCF.

Ai fini dei presenti scenari, si presuppone che le interfacce di base per Servizi remoti .NET siano analoghe a quelle illustrate nel seguente esempio.When reading through these scenarios, assume our baseline interfaces for .NET Remoting look like the following example. L'implementazione di Servizi remoti .NET non è importante in questo caso, perché si vuole solo illustrare come usare WCF per implementare una funzionalità equivalente.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) {…}  
}  

Scenario 1: il server restituisce un oggetto in base al valoreScenario 1: Service Returns an Object by Value

In questo scenario viene illustrato un server che restituisce al client un oggetto in base al valore.This scenario demonstrates a server returning an object to the client by value. Poiché WCF restituisce sempre gli oggetti dal server in base al valore, la procedura seguente descrive semplicemente come compilare un normale servizio WCF.WCF always returns objects from the server by value, so the following steps simply describe how to build a normal WCF service.

  1. Per iniziare, definire un'interfaccia pubblica per il servizio WCF e contrassegnarla con l'attributo [ServiceContract].Start by defining a public interface for the WCF service and mark it with the [ServiceContract] attribute. Viene usato [OperationContract] per identificare i metodi sul lato server che verranno chiamati dal client.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. Il passaggio successivo consiste nel creare il contratto dati per questo servizio.The next step is to create the data contract for this service. Tale operazione viene eseguita creando classi (non interfacce) contrassegnate con l'attributo [DataContract].We do this by creating classes (not interfaces) marked with the [DataContract] attribute. Le singole proprietà o i singoli campi che devono essere visibili sia per il client che per il server sono contrassegnati con [DataMember].The individual properties or fields we want visible to both client and server are marked with [DataMember]. Se si vuole che i tipi derivati siano consentiti, è necessario usare l'attributo [KnownType] per identificarli.If we want derived types to be allowed, we must use the [KnownType] attribute to identify them. Gli unici tipi di cui WCF consentirà la serializzazione o la deserializzazione per questo servizio sono quelli nell'interfaccia del servizio e questi "tipi noti".The only types WCF will allow to be serialized or deserialized for this service are those in the service interface and these "known types". Ogni tentativo di scambiare qualsiasi altro tipo non incluso in questo elenco verrà rifiutato.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. È quindi necessario fornire l'implementazione per l'interfaccia del servizio.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. Per eseguire il servizio WCF, è necessario dichiarare un endpoint che esponga tale interfaccia del servizio in un URL specifico tramite un'associazione WCF specifica.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. Questa operazione viene in genere eseguita aggiungendo le sezioni seguenti al file web.config del progetto server.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. Il servizio WCF può quindi essere avviato con il codice seguente:The WCF service can then be started with the following code:

ServiceHost customerServiceHost = new ServiceHost(typeof(CustomerService));  
    customerServiceHost.Open();  
 <span data-ttu-id="02a73-300">Quando questo ServiceHost viene avviato, usa il file web.config per stabilire il contratto, l'associazione e l'endpoint appropriati.</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-301">Per ulteriori informazioni sui file di configurazione, vedere [la configurazione di servizi tramite file di configurazione](./configuring-services-using-configuration-files.md).</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-302">Questo tipo di avvio del server è noto come self-hosting.</span><span class="sxs-lookup"><span data-stu-id="02a73-302">This style of starting the server is known as self-hosting.</span></span> <span data-ttu-id="02a73-303">Per ulteriori informazioni sulle altre opzioni di hosting dei servizi WCF, vedere [servizi di Hosting](./hosting-services.md).</span><span class="sxs-lookup"><span data-stu-id="02a73-303">To learn more about other choices for hosting WCF services, see [Hosting Services](./hosting-services.md).</span></span>  
  1. Il file app.config del progetto client deve dichiarare le informazioni di associazione corrispondenti per l'endpoint del servizio.The client project’s app.config must declare matching binding information for the service’s endpoint. Il modo più semplice per eseguire questa operazione in Visual Studio consiste nell'utilizzare Aggiungi riferimento al servizio, che aggiorna automaticamente il file app. config.The easiest way to do this in Visual Studio is to use Add Service Reference, which will automatically update the app.config file. In alternativa, è possibile apportare le stesse modifiche manualmente.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>  
    

    Per ulteriori informazioni sull'utilizzo Aggiungi riferimento al servizio, vedere procedura: aggiungere, aggiornare o rimuovere un riferimento al servizio.For more information about using Add Service Reference, see How to: Add, Update, or Remove a Service Reference.

  2. A questo punto è possibile chiamare il servizio WCF dal client.Now we can call the WCF service from the client. È possibile eseguire tale operazione creando una channel factory per il servizio, richiedendole un canale e chiamando direttamente il metodo desiderato su tale canale.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. Ciò è possibile perché il canale implementa l'interfaccia del servizio e gestisce automaticamente la logica di richiesta/risposta sottostante.We can do this because the channel implements the service’s interface and handles the underlying request/reply logic for us. Il valore restituito dalla chiamata del metodo è la copia deserializzata della risposta del server.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));  

Gli oggetti restituiti da WCF dal server al client sono sempre in base al valore.Objects returned by WCF from the server to the client are always by value. Gli oggetti sono copie deserializzate dei dati inviati dal server.The objects are deserialized copies of the data sent by the server. Il client può chiamare metodi su queste copie locali senza rischiare di richiamare codice server tramite callback.The client can call methods on these local copies without any danger of invoking server code through callbacks.

Scenario 2: il server restituisce un oggetto in base al riferimentoScenario 2: Server Returns an Object By Reference

In questo scenario viene illustrato un server che fornisce al client un oggetto in base al riferimento.This scenario demonstrates the server providing an object to the client by reference. In Servizi remoti .NET questa operazione viene gestita automaticamente per qualsiasi tipo derivato da MarshalByRefObject, che è serializzato in base al riferimento.In .NET Remoting, this is handled automatically for any type derived from MarshalByRefObject, which is serialized by-reference. Un esempio di questo scenario consiste nel consentire a più client di disporre di oggetti con sessione indipendenti sul lato server.An example of this scenario is allowing multiple clients to have independent sessionful server-side objects. Come accennato in precedenza, gli oggetti restituiti da un servizio WCF sono sempre in base al valore, pertanto non esiste un equivalente diretto di un oggetto in base al riferimento. Tuttavia, è possibile ottenere un risultato analogo a una semantica in base al riferimento usando un oggetto EndpointAddress10.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. Questo è un oggetto serializzabile in base al valore che può essere usato dal client per ottenere un oggetto in base al riferimento con sessione sul server.This is a serializable by-value object that can be used by the client to obtain a sessionful by-reference object on the server. Ciò rende possibile lo scenario relativo a più client con oggetti con sessione indipendenti sul lato server.This enables the scenario of having multiple clients with independent sessionful server-side objects.

  1. Innanzitutto, è necessario definire un contratto di servizio WCF che corrisponde all'oggetto con sessione stesso.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="02a73-323">Si noti che l'oggetto con sessione è contrassegnato con [ServiceContract], che lo rende una normale interfaccia del servizio WCF.</span><span class="sxs-lookup"><span data-stu-id="02a73-323">Notice that the sessionful object is marked with [ServiceContract], making it a normal WCF service interface.</span></span> <span data-ttu-id="02a73-324">L'impostazione della proprietà SessionMode indica che sarà un servizio con sessione.</span><span class="sxs-lookup"><span data-stu-id="02a73-324">Setting the SessionMode property indicates it will be a sessionful service.</span></span> <span data-ttu-id="02a73-325">In WCF una sessione è un modo per correlare più messaggi inviati tra due endpoint.</span><span class="sxs-lookup"><span data-stu-id="02a73-325">In WCF, a session is a way of correlating multiple messages sent between two endpoints.</span></span> <span data-ttu-id="02a73-326">Ciò significa che, una volta che un client ottiene una connessione al servizio, verrà stabilita una sessione tra il client e il server.</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-327">Il client userà una singola istanza univoca dell'oggetto sul lato server per tutte le proprie interazioni all'interno di questa singola sessione.</span><span class="sxs-lookup"><span data-stu-id="02a73-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. È quindi necessario fornire l'implementazione di questa interfaccia del servizio.Next, we need to provide the implementation of this service interface. Denotandola con [ServiceBehavior] e impostando InstanceContextMode, è possibile indicare a WCF che si vuole usare un'istanza univoca di questo tipo per ciascuna sessione.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. A questo punto è necessario un modo per ottenere un'istanza di questo oggetto con sessione.Now we need a way to obtain an instance of this sessionful object. A tale scopo, è possibile creare un'altra interfaccia di servizio WCF che restituisce un oggetto EndpointAddress10.We do this by creating another WCF service interface that returns an EndpointAddress10 object. Si tratta di una forma serializzabile di un endpoint che il client può usare per creare l'oggetto con sessione.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="02a73-333">È quindi possibile implementare il servizio WCF:</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-334">Questa implementazione mantiene una channel factory singleton per creare oggetti con sessione.</span><span class="sxs-lookup"><span data-stu-id="02a73-334">This implementation maintains a singleton channel factory to create sessionful objects.</span></span> <span data-ttu-id="02a73-335">Quando viene chiamato GetInstanceAddress(), questo crea un canale e un oggetto EndpointAddress10 che fa riferimento in modo efficace all'indirizzo remoto associato a questo canale.</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-336">EndpointAddress10 è semplicemente un tipo di dati che può essere restituito al client in base al valore.</span><span class="sxs-lookup"><span data-stu-id="02a73-336">EndpointAddress10 is simply a data type that can be returned to the client by-value.</span></span>  
  1. È necessario modificare il file di configurazione del server eseguendo le due operazioni seguenti, come illustrato nell'esempio riportato di seguito:We need to modify the server’s configuration file by doing the following two things as shown in the example below:

    1. Dichiarare un <client > sezione che descrive l'endpoint per l'oggetto con sessione.Declare a <client> section that describes the endpoint for the sessionful object. Questa operazione è necessaria perché il server opera anche come client in questa situazione.This is necessary because the server also acts as a client in this situation.

    2. Dichiarare gli endpoint per la factory e l'oggetto con sessione.Declare endpoints for the factory and sessionful object. Ciò è necessario per consentire al client di comunicare con gli endpoint del servizio per acquisire l'EndpointAddress10 e per creare il canale con sessione.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>  
    

    È quindi possibile avviare questi servizi:And then we can start these services:

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

ServiceHost sessionHost = new ServiceHost(typeof(MySessionBoundObject));  
sessionHost.Open();  
  1. Il client può essere configurato dichiarando questi stessi endpoint nel file app.config del progetto.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. Per creare e usare questo oggetto con sessione, il client deve eseguire le operazioni seguenti:In order to create and use this sessionful object, the client must do the following steps:

    1. Creare un canale per il servizio ISessionBoundFactory.Create a channel to the ISessionBoundFactory service.

    2. Usare tale canale per richiamare il servizio in modo da ottenere un EndpointAddress10.Use that channel to invoke that service to obtain an EndpointAddress10.

    3. Usare l'EndpointAddress10 per creare un canale in modo da ottenere un oggetto con sessione.Use the EndpointAddress10 to create a channel to obtain a sessionful object.

    4. Interagire con l'oggetto con sessione per verificare che rimanga la stessa istanza fra diverse chiamate.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 restituisce sempre oggetti in base al valore, ma è possibile supportare l'equivalente di una semantica in base al riferimento mediante l'uso di EndpointAddress10.WCF always returns objects by value, but it is possible to support the equivalent of by-reference semantics through the use of EndpointAddress10. Ciò consente al client di richiedere un'istanza del servizio WCF con sessione, dopodiché può interagire con tale istanza come qualsiasi altro servizio WCF.This permits the client to request a sessionful WCF service instance, after which it can interact with it like any other WCF service.

Scenario 3: il client invia al server un'istanza in base al valoreScenario 3: Client Sends Server a By-Value Instance

In questo scenario viene illustrato un client che invia al server un'istanza di oggetto non primitiva in base al valore.This scenario demonstrates the client sending a non-primitive object instance to the server by value. Poiché WCF invia solo oggetti in base al valore, in questo scenario viene illustrato il normale uso di WCF.Because WCF only sends objects by value, this scenario demonstrates normal WCF usage.

  1. Usare lo stesso servizio WCF dello scenario 1.Use the same WCF Service from Scenario 1.

  2. Usare il client per creare un nuovo oggetto in base al valore (Customer), creare un canale per comunicare con il servizio ICustomerService e inviare l'oggetto a tale canale.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="02a73-356">L'oggetto Customer verrà serializzato e inviato al server, dove sarà deserializzato in una nuova copia di tale oggetto.</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-357">Questo codice illustra inoltre l'invio di un tipo derivato (PremiumCustomer).</span><span class="sxs-lookup"><span data-stu-id="02a73-357">This code also illustrates sending a derived type (PremiumCustomer).</span></span> <span data-ttu-id="02a73-358">L'interfaccia del servizio prevede un oggetto Customer, ma l'attributo [KnownType] nella classe Customer indicava che anche PremiumCustomer era consentito.</span><span class="sxs-lookup"><span data-stu-id="02a73-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="02a73-359">In WCF qualunque tentativo di serializzare o deserializzare qualsiasi altro tipo tramite questa interfaccia di servizio non riuscirà.</span><span class="sxs-lookup"><span data-stu-id="02a73-359">WCF will fail any attempt to serialize or deserialize any other type through this service interface.</span></span>  

I normali scambi di dati in WCF sono in base al valore.Normal WCF exchanges of data are by value. Ciò garantisce che la chiamata di metodi su uno di questi oggetti di dati venga eseguita solo in locale: non verrà richiamato codice su un altro livello.This guarantees that invoking methods on one of these data objects executes only locally – it will not invoke code on the other tier. Sebbene sia possibile ottenere un risultato simile oggetti in base al riferimento restituiti da server, non è possibile che un client di passare un oggetto in base al riferimento per il 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. Uno scenario che richiede una conversazione tra il client e il server può essere realizzato in WCF usando un servizio duplex.A scenario that requires a conversation back and forth between client and server can be achieved in WCF using a duplex service. Per ulteriori informazioni, vedere servizi Duplex.For more information, see Duplex Services.

RiepilogoSummary

Servizi remoti .NET è un framework di comunicazione destinato all'uso solo all'interno di ambienti completamente attendibili..NET Remoting is a communication framework intended to be used only within fully-trusted environments. Si tratta di un prodotto legacy e supportato solo per la compatibilità con le versioni precedenti.It is a legacy product and supported only for backward compatibility. Non deve essere usato per creare nuove applicazioni.It should not be used to build new applications. Al contrario, WCF è stato progettato prestando particolare attenzione alla sicurezza ed è consigliato per le applicazioni nuove ed esistenti.Conversely, WCF was designed with security in mind and is recommended for new and existing applications. Microsoft consiglia di eseguire la migrazione delle applicazioni Servizi remoti .NET esistenti per l'uso di WCF o dell'API Web ASP.NET.Microsoft recommends that existing Remoting applications be migrated to use WCF or ASP.NET Web API instead.