具有输出缓存配置文件的WCF服务设置了Vary:*标头

问题描述

我有一个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()吗? 还有其他解决方法吗?

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

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

但没有效果

在OutputCacheProfile中设置location =“ ServerAndClient”也无济于事。

我正在考虑改为使用Web API控制器,并使用以下方法: https://github.com/filipw/Strathweb.CacheOutput,但这是不得已的方法。

更新

我尝试了以下来自丁鹏的建议,其中BeforeSendReply中的代码试图删除variable标头:

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

然而,variable *标头仍然出现在响应中,就像输出缓存机制在此点之后将其重新添加一样。

解决方法

您可以使用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,ClientRuntime clientRuntime)
    {
        return;
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription,DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.MessageInspectors.Add(new ServerMessageLogger());
    }

    public void Validate(ContractDescription contractDescription,ServiceEndpoint endpoint)
    {
        return;
    }
}

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

最后,我们需要对服务应用CustContractBehavior:

enter image description here

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

enter image description here

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...