问题描述
我有一个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:
下图是浏览器获得的响应头:
如果问题仍然存在,请随时告诉我。