WCF服务公开部分Web API

时间:2016-11-08 21:59:33

标签: c# web-services rest wcf dynamics-crm

我被赋予了创建WCF服务的任务,该服务仅公开部分oData REST API。只有WCF服务才会公开REST API允许的某些功能。 (WCF服务基本上充当过滤器)。

我的方法是什么?我知道我可以使用代理类调用WCF服务。但那些只是直接的方法调用。我不希望每个操作都有单独的功能。还有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

您可以选择通过WebApi在操作合同上添加属性[WebGet]公开哪些操作。

[OperationContract]
[WebGet]
string Method2(string s);

但是,如果您通过net.tcp公开服务,则没有默认方法可以为此协议禁用某些服务。

要管理此任务,您需要编写自定义行为,该行为将检查使用的协议,并允许执行调用或引发异常。

从custom属性开始,该属性定义可以通过所选通道执行的操作。

[OperationContract]
[WebGet]
[WcfAllowed]
string Method1(string s);

接下来,我们需要消息检查器,它将使用我们的自定义属性。 邮件检查器

  • 检查所选协议(net.tcp)。
  • 获取被调用的方法名称
  • 找到界面方法
  • 检查方法是否标记有我们的自定义属性
  • 如果没有抛出异常

以下代码:

public class DispatchMessageInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        if (channel is IServiceChannel serviceChannel)
        {
            if (serviceChannel.ListenUri.Scheme == "net.tcp")
            {
                string methodName=request.Headers.Action.Split('/').Last();
                TypeInfo serviceType = instanceContext.Host.Description.ServiceType as TypeInfo;
                foreach (var @interface in serviceType.ImplementedInterfaces)
                {
                    var method = @interface.GetMethod(methodName);
                    if (method != null)
                    {
                        var attributes = method.GetCustomAttributes().Where(x => x.GetType() == typeof(WcfAllowedAttribute)).FirstOrDefault();
                        if (attributes == null)
                        {
                            throw new OnyWebApiException($"Method which was invoked: {methodName}");
                        }
                    }
                }
            }
        }
        return request;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {

    }
 }

广告的最后一个要素是将我们的消息检查器与服务连接起来。为此,我们需要服务行为。

public class CustomServiceBehavior : Attribute, IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
       foreach(ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
        {
            foreach (var endpointDispatcher in channelDispatcher.Endpoints)
            {
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new DispatchMessageInspector());
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {

    }
}

服务行为需要连接到服务。最简单的方法是使用属性标记服务:

[CustomServiceBehavior]
public class CustomService : ICustomContract
{
    public string Method1(string s)
    {
        return s;
    }

    public string Method2(string s)
    {
        return s;
    }
}

我创建了solution来进行实际展示。如果您有兴趣,请结帐 OnlyNetTcp