【问题标题】:WCF Service with Output Cache Profile sets Vary: * header具有输出缓存配置文件集的 WCF 服务不同:* 标头
【发布时间】:2021-01-04 20:03:55
【问题描述】:

我有一个 WCF 服务,它使用 OutputCacheProfile 来获得一小时的输出缓存时间

<add name="GetVisitorSettingsCache" location="Any" duration="3600" enabled="true" varyByParam="groupid;service;site;ver" />

输出缓存有效,但响应包含标头Vary: *,这会阻止浏览器使用缓存的响应。 我相信我遇到了这里描述的错误: https://topic.alibabacloud.com/a/introduction-to-an-outputcache-bug-that-accompanied-asp-net-from-10-to-40_1_36_32422553.html 解决方法是致电Response.Cache.SetOmitVaryStar(true); 除了在我的情况下,我有 WCF 服务并且不知道如何在该上下文中使用解决方法

有什么方法可以为 WCF 服务调用 SetOmitVaryStar() 吗? 还有其他解决方法吗?

我尝试以编程方式设置可变标头:

WebOperationContext.Current.OutgoingResponse.Headers.Add("vary", "");

但是没有效果

在 OutputCacheProfile 中设置 location="ServerAndClient" 也没有帮助。

我正在考虑改用 Web API 控制器并使用它: https://github.com/filipw/Strathweb.CacheOutput 但这是最​​后的手段。

更新

我尝试了下面丁鹏的建议,BeforeSendReply 中的代码试图删除可变标头:

webOperationContext.OutgoingResponse.Headers.Remove("vary");

但是,vary * 标头仍然出现在响应中,就好像输出缓存机制在此点之后将其添加回来一样。

【问题讨论】:

    标签: wcf outputcache vary


    【解决方案1】:

    您可以使用 IDispatchMessageInspector 接口,这是我的演示:

    public class ServerMessageLogger : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            Console.WriteLine("OK");
            
            return null;
        }
    
        public void BeforeSendReply(ref Message reply, object correlationState)
        {
    
            WebOperationContext webOperationContext = WebOperationContext.Current;
            webOperationContext.OutgoingResponse.Headers.Add("vary", "*");
        }
    }
    

    我们可以在 IDispatchMessageInspector 中添加响应头。

    [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false)]
    public class CustContractBehaviorAttribute : Attribute, IContractBehavior
    {
        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }
    
        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            return;
        }
    
        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            dispatchRuntime.MessageInspectors.Add(new ServerMessageLogger());
        }
    
        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
            return;
        }
    }
    

    我们还需要将 ServerMessageLogger 添加到服务的行为中。

    最后我们需要将 CustContractBehavior 应用到服务中:

    下图是浏览器获取的响应头:

    如果问题仍然存在,请随时告诉我。

    【讨论】:

    • 我正在尝试这个。我实际上是在尝试 remove 变化标头。在“BeforeSendReply”中,我有: webOperationContext.OutgoingResponse.Headers.Add("testheader", "hello"); webOperationContext.OutgoingResponse.Headers.Remove("vary");我可以看到响应有 testheader :你好。但它仍然包括变化:*。调试器显示可变标头已被删除,但在那之后必须将其添加回来?
    • 不需要添加其他标题。
    • 另一个标题只是为了证明代码有效果。问题仍然是如何从响应中删除 vary : * 标头?
    • 为了判断输出缓存机制是否会在BeforeSendReply方法后面加上“vary”,我觉得可以检查一下BeforeSendReply方法中是否有“vary”。
    • 有趣的是,vary: * 标头已经存在于 BeforeSendReply 中,当我在调试器中检查标头时,删除它的代码(请参阅上面的更新答案)似乎可以工作。但响应仍然包括 Vary: *
    猜你喜欢
    • 2023-04-08
    • 2018-10-27
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    相关资源
    最近更新 更多