Procedimiento para publicar metadatos para un servicio mediante código
Este es uno de los dos temas de instrucciones para la publicación de metadatos para un servicio Windows Communication Foundation (WCF). Hay dos maneras de especificar cómo debería publicar metadatos un servicio: mediante un archivo de configuración y mediante código. En este tema se muestra cómo publicar metadatos para un servicio mediante código.
Precaución
En este tema se muestra cómo publicar metadatos de forma no segura. Cualquier cliente puede recuperar los metadatos del servicio. Si el servicio necesita publicar los metadatos de forma segura. Consulte Punto de conexión personalizado de metadatos seguros.
Para obtener más información sobre cómo publicar metadatos en un archivo de configuración, consulte Procedimiento para publicar metadatos para un servicio mediante un archivo de configuración. La publicación de metadatos permite a los clientes recuperar los metadatos mediante una solicitud GET WS-Transfer o mediante una solicitud HTTP/GET usando la cadena de solicitud ?wsdl
. Para asegurarse de que el código funciona, debe crear un servicio básico de WCF. En el código siguiente, se proporciona un servicio autohospedado básico.
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace Metadata.Samples
{
[ServiceContract]
public interface ISimpleService
{
[OperationContract]
string SimpleMethod(string msg);
}
class SimpleService : ISimpleService
{
public string SimpleMethod(string msg)
{
Console.WriteLine("The caller passed in " + msg);
return "Hello " + msg;
}
}
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
<ServiceContract()> _
Public Interface ISimpleService
<OperationContract()> _
Function SimpleMethod(ByVal msg As String) As String
End Interface
Class SimpleService
Implements ISimpleService
Public Function SimpleMethod(ByVal msg As String) As String Implements ISimpleService.SimpleMethod
Console.WriteLine("The caller passed in " + msg)
Return "Hello " + msg
End Function
End Class
Publicación de metadatos mediante código
Dentro del método principal de una aplicación de consola, cree instancias de un objeto ServiceHost pasando el tipo de servicio y la dirección base.
ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost:8001/MetadataSample"));
Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("http://localhost:8001/MetadataSample"))
Cree un bloque try justo debajo del código del paso 1, esto detecta cualquier excepción que se produzca mientras se está ejecutando el servicio.
try {
Try
} catch (CommunicationException commProblem) { Console.WriteLine("There was a communication problem. " + commProblem.Message); Console.Read(); }
Catch commProblem As CommunicationException Console.WriteLine("There was a communication problem. " + commProblem.Message) Console.Read() End Try
Compruebe si el host del servicio ya contiene un ServiceMetadataBehavior, si no, cree una nueva instancia de ServiceMetadataBehavior.
// Check to see if the service host already has a ServiceMetadataBehavior ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>(); // If not, add one if (smb == null) smb = new ServiceMetadataBehavior();
'Check to see if the service host already has a ServiceMetadataBehavior Dim smb As ServiceMetadataBehavior = svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)() 'If not, add one If (smb Is Nothing) Then smb = New ServiceMetadataBehavior() End If
Establezca la propiedad HttpGetEnabled en
true.
.smb.HttpGetEnabled = true;
smb.HttpGetEnabled = True
El ServiceMetadataBehavior contiene una propiedad MetadataExporter. El MetadataExporter contiene una propiedad PolicyVersion. Establezca el valor de la propiedad PolicyVersion en Policy15. La propiedad PolicyVersion también se puede establecer en Policy12. Cuando se establece en Policy15, el exportador de metadatos genera información de directivas con los metadatos que cumple la especificación WS-Policy 1.5. Cuando se establece en Policy12, el exportador de metadatos genera información de directivas conforme a la especificación WS-Policy 1.2.
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
Agregue la instancia de ServiceMetadataBehavior a la colección de comportamientos del host del servicio.
svcHost.Description.Behaviors.Add(smb);
svcHost.Description.Behaviors.Add(smb)
Agregue el punto de conexión de intercambio de metadatos al host de servicio.
// Add MEX endpoint svcHost.AddServiceEndpoint( ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex" );
'Add MEX endpoint svcHost.AddServiceEndpoint( _ ServiceMetadataBehavior.MexContractName, _ MetadataExchangeBindings.CreateMexHttpBinding(), _ "mex")
Agregue un extremo de la aplicación al host de servicio.
// Add application endpoint svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
'Add application endpoint svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
Nota
Si no agrega ningún punto de conexión al servicio, el tiempo de ejecución agregará los puntos de conexión predeterminados. En este ejemplo, dado que el servicio tiene un ServiceMetadataBehavior establecido en
true
, el servicio tiene habilitada la publicación de metadatos. Para obtener más información sobre los puntos de conexión predeterminados, consulte Configuración simplificada y Configuración simplificada de los servicios WCF.Abra el host de servicio y espere las llamadas entrantes. Cuando el usuario presione Entrar, cierre el host de servicio.
// Open the service host to accept incoming calls svcHost.Open(); // The service can now be accessed. Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.WriteLine(); Console.ReadLine(); // Close the ServiceHostBase to shutdown the service. svcHost.Close();
'Open the service host to accept incoming calls svcHost.Open() 'The service can now be accessed. Console.WriteLine("The service is ready.") Console.WriteLine("Press <ENTER> to terminate service.") Console.WriteLine() Console.ReadLine() 'Close the ServiceHostBase to shutdown the service. svcHost.Close()
Compilación y ejecución de la aplicación de consola.
Vaya a la dirección base del servicio (
http://localhost:8001/MetadataSample
en este ejemplo) y compruebe que la publicación de metadatos esté activada. Debería ver una página web que dice "Servicio Simple" en la parte superior y, justo debajo, "Ha creado un servicio". Si no, un mensaje en la parte superior de la página resultante muestra: "La publicación de metadatos para este servicio está deshabilitada actualmente".
Ejemplo
El siguiente código de ejemplo muestra la implementación de un servicio WCF básico que publica metadatos para el servicio mediante código.
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace Metadata.Samples
{
[ServiceContract]
public interface ISimpleService
{
[OperationContract]
string SimpleMethod(string msg);
}
class SimpleService : ISimpleService
{
public string SimpleMethod(string msg)
{
Console.WriteLine("The caller passed in " + msg);
return "Hello " + msg;
}
}
class Program
{
static void Main(string[] args)
{
ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost:8001/MetadataSample"));
try
{
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svcHost.Description.Behaviors.Add(smb);
// Add MEX endpoint
svcHost.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex"
);
// Add application endpoint
svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
// Open the service host to accept incoming calls
svcHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
svcHost.Close();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.Read();
}
}
}
}
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
<ServiceContract()> _
Public Interface ISimpleService
<OperationContract()> _
Function SimpleMethod(ByVal msg As String) As String
End Interface
Class SimpleService
Implements ISimpleService
Public Function SimpleMethod(ByVal msg As String) As String Implements ISimpleService.SimpleMethod
Console.WriteLine("The caller passed in " + msg)
Return "Hello " + msg
End Function
End Class
Module Module1
Sub Main()
Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("http://localhost:8001/MetadataSample"))
Try
'Check to see if the service host already has a ServiceMetadataBehavior
Dim smb As ServiceMetadataBehavior = svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)()
'If not, add one
If (smb Is Nothing) Then
smb = New ServiceMetadataBehavior()
End If
smb.HttpGetEnabled = True
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
svcHost.Description.Behaviors.Add(smb)
'Add MEX endpoint
svcHost.AddServiceEndpoint( _
ServiceMetadataBehavior.MexContractName, _
MetadataExchangeBindings.CreateMexHttpBinding(), _
"mex")
'Add application endpoint
svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
'Open the service host to accept incoming calls
svcHost.Open()
'The service can now be accessed.
Console.WriteLine("The service is ready.")
Console.WriteLine("Press <ENTER> to terminate service.")
Console.WriteLine()
Console.ReadLine()
'Close the ServiceHostBase to shutdown the service.
svcHost.Close()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " + commProblem.Message)
Console.Read()
End Try
End Sub
End Module