WCF ServiceContract中的筛选器方法

本文关键字:方法 筛选 ServiceContract WCF | 更新日期: 2023-09-27 18:25:22

我在一个ServiceHost中实现了多个ServiceContract。该服务可在网络内部和外部访问,并通过基于IP的方法属性授予访问权限:

[OperationContract]
[IPAuthentication(RequiredPermission = PermissionLevels.ExternalRead)]
bool Ping();

这很好,但客户端看到所有方法时会感到困惑,但只有几个方法没有访问限制,其他方法会抛出HttpStatusCode.Uuthorized异常。

我如何继承、扩展或更改ServiceContractAttribute以在客户端的WSDL中实现过滤的方法列表?

WCF ServiceContract中的筛选器方法

您可以通过IWsdlExportExtension控制WSDL的生成。

一个很好的例子可以在这里找到:

http://blogs.msdn.com/b/carlosfigueira/archive/2011/10/06/wcf-extensibility-wsdl-export-extension.aspx

不要忘记迭代所有wsdl文件以接触任何对象:

public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
    foreach (ServiceDescription wsdl in exporter.GeneratedWsdlDocuments)
    {
        List<string> messageNamesToRemove;
        RemoveOperationsFromPortTypes(wsdl, out messageNamesToRemove);
        List<string> policiesToRemove;
        RemoveOperationsFromBindings(wsdl, out policiesToRemove);
        RemoveWsdlMessages(wsdl, messageNamesToRemove);
        RemoveOperationRelatedPolicies(wsdl, policiesToRemove);
    }
}

如果所有方法都是隐藏的,请从PortTypes和Bindings:中删除空合约

private void RemoveOperationsFromPortTypes(ServiceDescription wsdl, out List<string> messageNamesToRemove)
{
    messageNamesToRemove = new List<string>();
    var emptyPorts = new List<System.Web.Services.Description.PortType>();
    foreach (System.Web.Services.Description.PortType portType in wsdl.PortTypes)
    {
        for (int i = portType.Operations.Count - 1; i >= 0; i--)
        {
            ...
            if (portType.Operations.Count == 0)
                emptyPorts.Add(portType);
        }
    }
    foreach (var emptyPort in emptyPorts)
    {
        wsdl.PortTypes.Remove(emptyPort);
    }
}
private void RemoveOperationsFromBindings(ServiceDescription wsdl, out List<string> policiesToRemove)
{
    policiesToRemove = new List<string>();
    var emptyBindings = new List<System.Web.Services.Description.Binding>();
    foreach (System.Web.Services.Description.Binding binding in wsdl.Bindings)
    {
        for (int i = binding.Operations.Count - 1; i >= 0; i--)
        {
            ...
        }
        if (binding.Operations.Count == 0)
            emptyBindings.Add(binding);
    }
    foreach (var emptyBinding in emptyBindings)
    {
        wsdl.Bindings.Remove(emptyBinding);
    }
}