Procedura: accedere a servizi WCF con un contratto unidirezionale o request/reply
Le procedure seguenti descrivono come accedere a un servizio Windows Communication Foundation (WCF) che definisce un contratto unidirezionale o un contratto request/reply e in cui non viene utilizzato il modello di comunicazione duplex.
Per definire il servizio
Dichiarare il contratto di servizio. Per le operazioni che devono essere unidirezionali
IsOneWay
deve essere impostato sutrue
all'interno di OperationContractAttribute. Nel codice seguente viene dichiarato il contrattoIOneWayCalculator
con operazioni unidirezionali perAdd
,Subtract
,Multiply
eDivide
. Viene inoltre definita un'operazione di richiesta/risposta chiamataSayHello
.[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")] public interface IOneWayCalculator { [OperationContract(IsOneWay = true)] void Add(double n1, double n2); [OperationContract(IsOneWay = true)] void Subtract(double n1, double n2); [OperationContract(IsOneWay = true)] void Multiply(double n1, double n2); [OperationContract(IsOneWay = true)] void Divide(double n1, double n2); [OperationContract] string SayHello(string name); }
Implementare il contratto di servizio Nel codice seguente viene implementata l'interfaccia
IOnewayCalculator
.[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)] public class CalculatorService : IOneWayCalculator { public void Add(double n1, double n2) { double result = n1 + n2; Console.WriteLine("Add({0},{1}) = {2} ", n1, n2, result); } public void Subtract(double n1, double n2) { double result = n1 - n2; Console.WriteLine("Subtract({0},{1}) = {2}", n1, n2, result); } public void Multiply(double n1, double n2) { double result = n1 * n2; Console.WriteLine("Multiply({0},{1}) = {2}", n1, n2, result); } public void Divide(double n1, double n2) { double result = n1 / n2; Console.WriteLine("Divide({0},{1}) = {2}", n1, n2, result); } public string SayHello(string name) { Console.WriteLine("SayHello({0})", name); return "Hello " + name; } }
Ospitare il servizio in un'applicazione console. Nel codice seguente viene illustrato come ospitare il servizio.
// Host the service within this EXE console application. public static void Main() { // Define the base address for the service. Uri baseAddress = new Uri("https://localhost:8000/servicemodelsamples/service"); // Create a ServiceHost for the CalculatorService type and provide the base address. using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress)) { // Add an endpoint using the IOneWayCalculator contract and the WSHttpBinding serviceHost.AddServiceEndpoint(typeof(IOneWayCalculator), new WSHttpBinding(), ""); // Turn on the metadata behavior, this allows svcutil to get metadata for the service. ServiceMetadataBehavior smb = (ServiceMetadataBehavior) serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>(); if (smb == null) { smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; serviceHost.Description.Behaviors.Add(smb); } // Open the ServiceHostBase to create listeners and start listening for messages. serviceHost.Open(); // The service can now be accessed. Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.WriteLine(); Console.ReadLine(); } }
Per accedere al servizio
Eseguire ServiceModel Metadata Utility Tool (Svcutil.exe) utilizzando l'indirizzo endpoint di scambio metadati per creare la classe client per il servizio utilizzando la riga di comando seguente:
Svcutil https://localhost:8000/Service
ServiceModel Metadata Utility Tool (Svcutil.exe) genera un set di interfacce e classi, come illustrato nel codice di esempio seguente.[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="IOneWayCalculator")] public interface IOneWayCalculator { [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.ServiceModel.Samples/IOneWayCalculator/Add")] void Add(double n1, double n2); [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.ServiceModel.Samples/IOneWayCalculator/Subtract")] void Subtract(double n1, double n2); [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.ServiceModel.Samples/IOneWayCalculator/Multiply")] void Multiply(double n1, double n2); [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.ServiceModel.Samples/IOneWayCalculator/Divide")] void Divide(double n1, double n2); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/IOneWayCalculator/SayHello", ReplyAction="http://Microsoft.ServiceModel.Samples/IOneWayCalculator/SayHelloResponse")] string SayHello(string name); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public interface IOneWayCalculatorChannel : IOneWayCalculator, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class OneWayCalculatorClient : System.ServiceModel.ClientBase<IOneWayCalculator>, IOneWayCalculator { public OneWayCalculatorClient() { } public OneWayCalculatorClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public OneWayCalculatorClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public OneWayCalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public OneWayCalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public void Add(double n1, double n2) { base.Channel.Add(n1, n2); } public void Subtract(double n1, double n2) { base.Channel.Subtract(n1, n2); } public void Multiply(double n1, double n2) { base.Channel.Multiply(n1, n2); } public void Divide(double n1, double n2) { base.Channel.Divide(n1, n2); } public string SayHello(string name) { return base.Channel.SayHello(name); } }
Si noti che nell'interfaccia
IOneWayCalculator
l'attributo IsOneWaydelle operazioni del servizio unidirezionale è impostato su true e l'attibuto dell'operazione del servizio richiesta/risposta è impostato sul valore predefinito false. Si noti inoltre la classeOneWayCalculatorClient
. Si tratta della classe che verrà utilizzata per chiamare il servizio.Creare l'oggetto client.
// Create a client WSHttpBinding binding = new WSHttpBinding(); EndpointAddress epAddress = new EndpointAddress("https://localhost:8000/servicemodelsamples/service"); OneWayCalculatorClient client = new OneWayCalculatorClient(binding, epAddress);
Chiamare le operazioni del servizio.
// Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; client.Add(value1, value2); Console.WriteLine("Add({0},{1})", value1, value2); // Call the Subtract service operation. value1 = 145.00D; value2 = 76.54D; client.Subtract(value1, value2); Console.WriteLine("Subtract({0},{1})", value1, value2); // Call the Multiply service operation. value1 = 9.00D; value2 = 81.25D; client.Multiply(value1, value2); Console.WriteLine("Multiply({0},{1})", value1, value2); // Call the Divide service operation. value1 = 22.00D; value2 = 7.00D; client.Divide(value1, value2); Console.WriteLine("Divide({0},{1})", value1, value2); // Call the SayHello service operation string name = "World"; string response = client.SayHello(name); Console.WriteLine("SayHello([0])", name); Console.WriteLine("SayHello() returned: " + response);
Chiudere il client per chiudere le connessioni e liberare risorse.
//Closing the client gracefully closes the connection and cleans up resources client.Close();
Esempio
Di seguito è riportato un elenco completo del codice utilizzato in questo argomento.
// Service.cs
using System;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface IOneWayCalculator
{
[OperationContract(IsOneWay = true)]
void Add(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Subtract(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Multiply(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Divide(double n1, double n2);
[OperationContract]
string SayHello(string name);
}
// Service class which implements the service contract.
// Added code to write output to the console window
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
public void Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Add({0},{1}) = {2} ", n1, n2, result);
}
public void Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Subtract({0},{1}) = {2}", n1, n2, result);
}
public void Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Multiply({0},{1}) = {2}", n1, n2, result);
}
public void Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Divide({0},{1}) = {2}", n1, n2, result);
}
public string SayHello(string name)
{
Console.WriteLine("SayHello({0})", name);
return "Hello " + name;
}
// Host the service within this EXE console application.
public static void Main()
{
// Define the base address for the service.
Uri baseAddress = new Uri("https://localhost:8000/servicemodelsamples/service");
// Create a ServiceHost for the CalculatorService type and provide the base address.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
// Add an endpoint using the IOneWayCalculator contract and the WSHttpBinding
serviceHost.AddServiceEndpoint(typeof(IOneWayCalculator), new WSHttpBinding(), "");
// Turn on the metadata behavior, this allows svcutil to get metadata for the service.
ServiceMetadataBehavior smb = (ServiceMetadataBehavior) serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
serviceHost.Description.Behaviors.Add(smb);
}
// Open the ServiceHostBase to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
}
}
// client.cs
using System;
using System.ServiceModel;
namespace Microsoft.ServiceModel.Samples
{
//The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.
//Client implementation code.
class Client
{
static void Main()
{
// Create a client
WSHttpBinding binding = new WSHttpBinding();
EndpointAddress epAddress = new EndpointAddress("https://localhost:8000/servicemodelsamples/service");
OneWayCalculatorClient client = new OneWayCalculatorClient(binding, epAddress);
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
client.Add(value1, value2);
Console.WriteLine("Add({0},{1})", value1, value2);
// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1})", value1, value2);
// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1})", value1, value2);
// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1})", value1, value2);
// Call the SayHello service operation
string name = "World";
string response = client.SayHello(name);
Console.WriteLine("SayHello([0])", name);
Console.WriteLine("SayHello() returned: " + response);
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}
}
}