0

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

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

输出缓存有效,但响应包含 header 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 * 标头仍然出现在响应中,就好像输出缓存机制在此之后将其添加回来一样。

4

1 回答 1

0

您可以使用 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 应用于服务:

在此处输入图像描述

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

在此处输入图像描述

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

于 2020-09-21T03:01:46.733 回答