2010-10-21 47 views
0

我在使用.NET4-IIS7上的WCF REST服務時遇到OutputCaching問題。我的服務有一個自定義的授權方案(通過實現ServiceAuthorizationManager),一個應該在每個請求上進行,並且任何緩存都必須在請求被授權後完成。到目前爲止,這似乎工作,只有緩存部分我看不到發生。帶有流的WCF .NET 4 OutputCaching似乎不起作用

我有以下OperationContract的:

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

而下面的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> 

我可以看到充滿了客戶端緩存的信息,當我撥打服務新的響應頭,但在服務器上緩存似乎不起作用。我的自定義日誌顯示我的api.Authorization類被正確調用,但我的getPage()方法也正常執行,直到我的文件正在將.OpenRead()寫入一個Stream並返回:

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); 
} 

如果正在緩存輸出,則不應該執行此方法......我期望Stream可以被緩存並直接服務,不需要查詢數據庫和磁盤讀取。每個zip文件大小約爲1 MB。 我錯過了什麼或做錯了什麼?

回答

0

經過一段時間的設置後,答案出來了:即使您實現自己的OutputCacheProvider,如果transferMode正在流式傳輸,OutputCache將不起作用。其原因在於,在流式響應方案中,您告訴WCF 而不是將您的響應緩衝在內存中,並嘗試從任何地方讀取它並將其發送到傳輸級別。 OutputCache依賴於完全在內存中的對象在返回之前,這樣WCF就可以保存對它的引用並將其放到緩存中。

在您的場景中,如果啓用不帶輸出緩存的流式傳輸比閱讀並保留內存中的對象更快,那麼您可以直接輸出它。