Como: publicar metadados utilizando código para um serviço
Este é um dos dois tópicos de instruções que discutem a publicação de metadados para um serviço do WCF (Windows Communication Foundation). Há duas maneiras de especificar como um serviço deve publicar metadados, usando um arquivo de configuração e usando código. Este tópico mostra como publicar metadados para um serviço usando um código.
Cuidado
Este tópico mostra como publicar metadados de maneira não segura. Qualquer cliente pode recuperar os metadados do serviço. Se você precisar que seu serviço publique metadados de maneira segura. confira Ponto de extremidade de metadados seguros personalizados.
Para obter mais informações sobre como publicar metadados em um arquivo de configuração, consulte Como publicar metadados para um serviço usando um arquivo de configuração. Publicar metadados permite que os clientes recuperem os metadados usando uma solicitação GET WS-Transfer ou uma solicitação HTTP/GET usando a cadeia de caracteres de consulta ?wsdl
. Para ter certeza de que o código está funcionando, você deve criar um serviço WCF básico. Um serviço auto-hospedado básico é fornecido no código a seguir.
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
Para publicar metadados no código
Dentro do método principal de um aplicativo de console, instancie um objeto ServiceHost passando o tipo de serviço e o endereço 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"))
Crie um bloco de tentativa imediatamente abaixo do código para a etapa 1, isso captura todas as exceções que são lançadas enquanto o serviço estiver em execução.
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
Verifique se o host de serviço já contém uma ServiceMetadataBehavior, caso contrário, crie uma nova instância 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
Defina a propriedade HttpGetEnabled como
true.
smb.HttpGetEnabled = true;
smb.HttpGetEnabled = True
O ServiceMetadataBehavior contém uma propriedade MetadataExporter. O MetadataExporter contém uma propriedade PolicyVersion. Defina o valor da propriedade PolicyVersion como Policy15. A propriedade PolicyVersion também pode ser definida como Policy12. Quando definido como Policy15, o exportador de metadados gera informações de política com os metadados que estão em conformidade com a WS-Policy 1.5. Quando definido como Policy12, o exportador de metadados gera informações de política com os metadados que" estão em conformidade com a WS-Policy 1.2.
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
Adicione a instância ServiceMetadataBehavior à coleção de comportamentos do host de serviço.
svcHost.Description.Behaviors.Add(smb);
svcHost.Description.Behaviors.Add(smb)
Adicione o ponto de extremidade de troca de metadados ao host de serviço.
// Add MEX endpoint svcHost.AddServiceEndpoint( ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex" );
'Add MEX endpoint svcHost.AddServiceEndpoint( _ ServiceMetadataBehavior.MexContractName, _ MetadataExchangeBindings.CreateMexHttpBinding(), _ "mex")
Adicione um ponto de extremidade de aplicativo ao host de serviço.
// Add application endpoint svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
'Add application endpoint svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
Observação
Se você não adicionar nenhum ponto de extremidade ao serviço, o runtime adicionará pontos de extremidade padrão para você. Neste exemplo, como o serviço tem ServiceMetadataBehavior definido como
true
, o serviço possui metadados de publicação habilitados. Para obter mais informações sobre pontos de extremidade padrão, consulte Configuração simplificada e Configuração simplificada para serviços WCF.Abra o host de serviço e aguarde as chamadas recebidas. Quando o usuário pressionar ENTER, feche o host de serviço.
// 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()
Crie e execute o aplicativo de console.
Navegue até o endereço base do serviço (
http://localhost:8001/MetadataSample
neste exemplo) e verificar se a publicação de metadados está ativada. Deve ser exibida uma página da Web que diz "Serviço Simples" na parte superior e imediatamente abaixo "Você criou um serviço". Caso contrário, uma mensagem na parte superior da página resultante será exibida: "A publicação de metadados para esse serviço está desabilitada no momento".
Exemplo
O exemplo de código a seguir mostra a implementação de um serviço WCF básico que publica metadados para o serviço no 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