views:

7

answers:

1

Hello,

I'm having problems with OutputCaching over a WCF REST service on .NET4-IIS7. My service has a custom Authorization scheme (by implementing ServiceAuthorizationManager), one which should take place on every request, and any caching must be done after the request is authorized. So far, this seems to work, only the caching part I can't see happening.

I have the following OperationContract:

[OperationContract]
[AspNetCacheProfile("PageZIP")]
[WebGet(UriTemplate = "pages/{page_id}")]
System.IO.Stream getPage(string page_id);

And the following web.config:

<system.web>
<compilation targetFramework="4.0" />
<customErrors mode="Off" />
<authentication mode="None" />
<caching>
    <outputCache enableOutputCache="true"/>
    <outputCacheSettings>
        <outputCacheProfiles>
            <add name="PageZIP" duration="7200" location="ServerAndClient"
                     varyByParam="page_id" />
        </outputCacheProfiles>
    </outputCacheSettings>
</caching>
</system.web>
    <system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceAuthorization serviceAuthorizationManagerType="api.Authorization, api" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
        <webHttpEndpoint>
            <standardEndpoint transferMode="StreamedResponse" automaticFormatSelectionEnabled="false" defaultOutgoingResponseFormat="Json" />
        </webHttpEndpoint>
    </standardEndpoints></system.serviceModel>

I can see the new response headers filled with client-side cache information when I call the service, but caching at the server doesn't seem to work. My custom log shows that my api.Authorization class is (rightly) being called, but my getPage() method is also executing as normal, up to the point where my file is being .OpenRead() into a Stream and returned:

public System.IO.Stream getPage(string page_id) {
    File zip = FileMapper.getZip(pid);
    ctx.OutgoingResponse.Headers.Clear();
    ctx.OutgoingResponse.Headers.Add("Content-Disposition", "attachment; filename=" + page_id + ".zip");
    ctx.OutgoingResponse.Headers.Add("Content-Length", zip.size.ToString());
    ctx.OutgoingResponse.ContentType = "application/zip";

    Log.write("OpenRead", LogType.Info);
    return System.IO.File.OpenRead(zip.path);
}

If output is being cached, this method shouldn't be executed at all... I expect the Stream to be cached and be served directly, without queries to the database and disk reads. Every zipfile is about 1 MB in size. What am I missing or doing wrong?