WCF Service with Output Cache Profile sets Vary: * header

148 Views Asked by At

I have a WCF service which uses an OutputCacheProfile to get a one hour output cache time

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

The output caching works, but responses include header Vary: *, which prevents the browser from using a cached the response. I believe I am running into the bug described here: https://topic.alibabacloud.com/a/introduction-to-an-outputcache-bug-that-accompanied-asp-net-from-10-to-40_1_36_32422553.html The workaround is to call Response.Cache.SetOmitVaryStar(true); except in my case I have a WCF service and do not know how to use the workaround in that context

Is there any way to call SetOmitVaryStar() for a WCF service? Is there some other workaround?

I tried programmatically setting the vary header:

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

but it had no effect

Setting location="ServerAndClient" in the OutputCacheProfile did not help either.

I am thinking of using a Web API controller instead and using this: https://github.com/filipw/Strathweb.CacheOutput but that is a last resort.

Update

I tried the suggestion from Ding Peng below, with code in BeforeSendReply attempting to remove the vary header:

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

However the vary * header still appears in the response, as if the output cache mechanism is adding it back after this point.

1

There are 1 best solutions below

5
On

You can use IDispatchMessageInspector interface, here is my demo:

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", "*");
    }
}

We can add response headers in 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;
    }
}

We also need to add ServerMessageLogger to the behavior of the service.

Finally we need to apply CustContractBehavior to the service:

enter image description here

The following figure is the response header obtained by the browser:

enter image description here

Feel free to let me know if the problem persists.