2010-10-21 2 views
0

У меня возникли проблемы с OutputCaching над службой WCF REST на .NET4-IIS7. У моего сервиса есть настраиваемая схема авторизации (путем внедрения 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() в поток и вернулся:

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 будет кэшироваться и обслуживаться напрямую, без запросов к базе данных и чтениям диска. Каждый zipfile имеет размер около 1 МБ. Что мне не хватает или что-то не так?

ответ

0

После игры с настройками на некоторое время, ответ вышел: OutputCache не будет работать, если transferMode струится, даже если вы реализуете свой собственный OutputCacheProvider. Причина этого заключается в том, что в потоковом сценарии ответа вы сообщаете WCF не, чтобы закрепить свой ответ в памяти и попытаться прочитать его откуда угодно и отправить его на уровень транспорта. OutputCache зависит от того, полностью ли объект находится в памяти, прежде чем он будет возвращен, так что WCF может сохранить ссылку на него и поместить его в кеш.

Это зависит от вас, чтобы увидеть в своем сценарии, если включение потоковой передачи без выходного кэша выполняется быстрее, чем чтение и хранение объекта в памяти, поэтому вы можете напрямую его выводить.

Смежные вопросы