我被赋予了创建WCF服务的任务,该服务仅公开部分oData REST API。只有WCF服务才会公开REST API允许的某些功能。 (WCF服务基本上充当过滤器)。
我的方法是什么?我知道我可以使用代理类调用WCF服务。但那些只是直接的方法调用。我不希望每个操作都有单独的功能。还有更好的方法吗?
答案 0 :(得分:0)
您可以选择通过WebApi在操作合同上添加属性[WebGet]公开哪些操作。
[OperationContract]
[WebGet]
string Method2(string s);
但是,如果您通过net.tcp公开服务,则没有默认方法可以为此协议禁用某些服务。
要管理此任务,您需要编写自定义行为,该行为将检查使用的协议,并允许执行调用或引发异常。
从custom属性开始,该属性定义可以通过所选通道执行的操作。
[OperationContract]
[WebGet]
[WcfAllowed]
string Method1(string s);
接下来,我们需要消息检查器,它将使用我们的自定义属性。 邮件检查器
以下代码:
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 。