如何将自定义响应作为 WCF 行为返回?

问题描述 投票:0回答:1

我希望能够像这样装饰 WCF 服务和端点:

[CacheBehavior]
public class MyService
{ }

调用操作时,我希望能够将请求 URL 作为缓存键进行查找,如果找到缓存的响应,则通过从缓存中获取预格式化的 JSON 字符串来立即返回原始响应。通过这样做,我可以避免调用实际的端点方法。

当在缓存中找不到操作时,我想在返回响应时执行一些逻辑,并使用相同的缓存键将原始响应(JSON)写入我的缓存。

我查看了https://github.com/dotnet/samples/tree/main/framework/wcf的示例,并尝试使用 ChannelMessageInterceptor、ChannelDispatcherBase、IDispatchMessageInspector 和 IOperationInvoker,但这些似乎都不支持这种使用案件。除非我错过了什么。

c# .net wcf caching
1个回答
0
投票

我能够在这个用例中使用

IOperationInvoker
,唯一需要注意的是它无法缓存预序列化响应,因为它期望返回一个对象。因此,在缓存或从缓存中获取时,我必须序列化/反序列化响应。

带有内存缓存的模拟代码:

public class CacheOperationInvoker : IOperationInvoker
{
    private static readonly Dictionary<string, object> _cache = new Dictionary<string, object>();

    private readonly IOperationInvoker _invoker;

    public bool IsSynchronous => true;

    public CacheOperationInvoker(IOperationInvoker baseInvoker)
    {
        this._invoker = baseInvoker;
    }

    public object[] AllocateInputs()
    {
        return _invoker.AllocateInputs();
    }

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        var operationContext = WebOperationContext.Current;

        var cacheKey = operationContext?.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString;

        if (_cache.ContainsKey(cacheKey))
        {
            outputs = new object[] { };
            return _cache[cacheKey];
        }

        var result = _invoker.Invoke(instance, inputs, out outputs);

        _cache[cacheKey] = result;

        return result;
    }

    public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
    {
        throw new Exception("The operation invoker is not asynchronous.");
    }

    public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
    {
        throw new Exception("The operation invoker is not asynchronous.");
    }
}

否则,我缺少的部分是需要使用

OperationContext.Current
WebOperationContext.Current
从传入请求访问其他上下文,因为它没有直接提供给
IOperationInvoker

© www.soinside.com 2019 - 2024. All rights reserved.