Obsługa buforowania dla internetowych usług HTTP programu WCF
Program .NET Framework 4.6.1 umożliwia korzystanie z mechanizmu buforowania deklaratywnego dostępnego już w ASP.NET w usługach HTTP sieci Web WCF. Ten mechanizm umożliwia buforowanie odpowiedzi z operacji protokołu HTTP w sieci Web WCF. Gdy użytkownik wysyła wiadomość HTTP GET
do usługi skonfigurowanej do buforowania, ASP.NET wysyła z powrotem buforowane odpowiedzi, a metoda usługi nie jest wywoływana. Gdy pamięć podręczna wygaśnie, następnym razem, gdy użytkownik wyśle metodę HTTP GET
, metoda usługi zostanie wywołana i odpowiedź zostanie ponownie buforowana. Aby uzyskać więcej informacji na temat buforowania ASP.NET, zobacz ASP.NET Caching Overview (Omówienie buforowania ASP.NET).
Podstawowa buforowanie usługi HTTP w sieci Web
Aby włączyć buforowanie usługi HTTP w sieci Web, należy najpierw włączyć ASP.NET zgodność, stosując AspNetCompatibilityRequirementsAttribute ustawienie usługi na Allowed wartość lub RequiredRequirementsMode .
Program .NET Framework 4 wprowadza nowy atrybut o nazwie AspNetCacheProfileAttribute , który umożliwia określenie nazwy profilu pamięci podręcznej. Ten atrybut jest stosowany do operacji usługi. Poniższy przykład dotyczy AspNetCompatibilityRequirementsAttribute usługi w celu włączenia zgodności ASP.NET i skonfigurowania GetCustomer
operacji buforowania. Atrybut AspNetCacheProfileAttribute określa profil pamięci podręcznej, który zawiera ustawienia pamięci podręcznej do użycia.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
[WebGet(UriTemplate = "{id}")]
[AspNetCacheProfile("CacheFor60Seconds")]
public Customer GetCustomer(string id)
{
// ...
}
}
Włącz również tryb zgodności ASP.NET w pliku Web.config, jak pokazano w poniższym przykładzie.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Ostrzeżenie
Jeśli ASP.NET tryb zgodności nie jest włączony i AspNetCacheProfileAttribute zostanie zgłoszony wyjątek.
Nazwa profilu pamięci podręcznej określona przez AspNetCacheProfileAttribute element identyfikuje profil pamięci podręcznej dodany do pliku konfiguracji Web.config. Profil pamięci podręcznej jest definiowany za pomocą elementu, <outputCacheSetting>
jak pokazano w poniższym przykładzie konfiguracji.
<!-- ... -->
<system.web>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor60Seconds" duration="60" varyByParam="none" sqlDependency="MyTestDatabase:MyTable"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<!-- ... -->
</system.web>
Jest to ten sam element konfiguracji, który jest dostępny dla ASP.NET aplikacji. Aby uzyskać więcej informacji na temat profilów pamięci podręcznej ASP.NET, zobacz OutputCacheProfile. W przypadku internetowych usług HTTP najważniejsze atrybuty w profilu pamięci podręcznej to: cacheDuration
i varyByParam
. Oba te atrybuty są wymagane. cacheDuration
Ustawia czas buforowania odpowiedzi w sekundach. varyByParam
Umożliwia określenie parametru ciągu zapytania używanego do buforowania odpowiedzi. Wszystkie żądania wysyłane z różnymi wartościami parametrów ciągu zapytania są buforowane oddzielnie. Na przykład po wysłaniu początkowego żądania do http://MyServer/MyHttpService/MyOperation?param=10
usługi wszystkie kolejne żądania wysyłane za pomocą tego samego identyfikatora URI będą zwracać buforowaną odpowiedź (o ile czas trwania pamięci podręcznej nie upłynął). Odpowiedzi dla podobnego żądania, które jest takie samo, ale mają inną wartość parametru ciągu zapytania, są buforowane oddzielnie. Jeśli nie chcesz tego oddzielnego zachowania buforowania, ustaw wartość varyByParam
"none".
Zależność pamięci podręcznej SQL
Odpowiedzi usługi HTTP sieci Web można również buforować za pomocą zależności pamięci podręcznej SQL. Jeśli usługa HTTP sieci Web WCF zależy od danych przechowywanych w bazie danych SQL, może być konieczne buforowanie odpowiedzi usługi i unieważnienie buforowanej odpowiedzi po zmianie danych w tabeli bazy danych SQL. To zachowanie jest konfigurowane całkowicie w pliku Web.config. Najpierw zdefiniuj parametry połączenia w elemecie <connectionStrings>
.
<connectionStrings>
<add name="connectString"
connectionString="..."
providerName="System.Data.SqlClient" />
</connectionStrings>
Następnie włącz zależność pamięci podręcznej SQL w elemecie w elemecie <caching>
<system.web>
, jak pokazano w poniższym przykładzie konfiguracji.
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="1000">
<databases>
<add name="MyTestDatabase" connectionStringName="connectString" />
</databases>
</sqlCacheDependency>
<!-- ... -->
</caching>
<!-- ... -->
</system.web>
W tym miejscu jest włączona zależność pamięci podręcznej SQL, a czas sondowania wynosi 1000 milisekund. Za każdym razem, gdy upłynie czas sondowania, tabela bazy danych jest sprawdzana pod kątem aktualizacji. Jeśli zostaną wykryte zmiany zawartości pamięci podręcznej zostaną usunięte, a przy następnym wywołaniu operacji usługi zostanie buforowana nowa odpowiedź. W elemencie <sqlCacheDependency>
dodaj bazy danych i odwołaj się do parametry połączenia w elemencie<databases>
, jak pokazano w poniższym przykładzie.
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="1000">
<databases>
<add name="MyTestDatabase" connectionStringName="connectString" />
</databases>
</sqlCacheDependency>
<!-- ... -->
</caching>
<!-- ... -->
</system.web>
Następnie należy skonfigurować ustawienia wyjściowej pamięci podręcznej w elemecie <caching>
, jak pokazano w poniższym przykładzie.
<system.web>
<caching>
<!-- ... -->
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor60Seconds" duration="60" varyByParam="none" sqlDependency="MyTestDatabase:MyTable" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<!-- ... -->
</system.web>
Tutaj czas trwania pamięci podręcznej jest ustawiony na 60 sekund, varyByParam
jest ustawiony na brak i sqlDependency
jest ustawiony na rozdzielaną średnikami listę par nazw/tabel bazy danych oddzielonych dwukropkami. Gdy dane w pliku MyTable
zostaną zmienione, buforowana odpowiedź dla operacji usługi zostanie usunięta i gdy operacja zostanie wywołana, zostanie wygenerowana nowa odpowiedź (wywołując operację usługi), buforowana i zwracana do klienta.
Ważne
Aby ASP.NET uzyskać dostęp do bazy danych SQL, należy użyć narzędzia ASP.NET rejestracji programu SQL Server. Ponadto należy zezwolić na odpowiedni dostęp konta użytkownika do bazy danych i tabeli. Aby uzyskać więcej informacji, zobacz Uzyskiwanie dostępu do programu SQL Server z poziomu aplikacji internetowej.
Warunkowe buforowanie oparte na protokole HTTP GET
W scenariuszach protokołu HTTP sieci Web warunkowe get http jest często używane przez usługi do implementowania inteligentnego buforowania HTTP zgodnie ze specyfikacją HTTP. W tym celu usługa musi ustawić wartość nagłówka ETag w odpowiedzi HTTP. Musi również sprawdzić nagłówek If-None-Match w żądaniu HTTP, aby sprawdzić, czy którykolwiek z określonych elementów ETag pasuje do bieżącego elementu ETag.
W przypadku żądań CheckConditionalRetrieve GET i HEAD przyjmuje wartość ETag i sprawdza ją względem nagłówka If-None-Match żądania. Jeśli nagłówek jest obecny i istnieje dopasowanie, WebFaultException zostanie zgłoszony kod stanu HTTP 304 (niezmodyfikowany), a nagłówek ETag zostanie dodany do odpowiedzi z pasującym elementem ETag.
Jedno przeciążenie CheckConditionalRetrieve metody przyjmuje datę ostatniej modyfikacji i sprawdza ją względem nagłówka If-Modified-Since żądania. Jeśli nagłówek jest obecny, a zasób nie został zmodyfikowany od tego czasu, WebFaultException zgłaszany jest kod stanu HTTP 304 (niezmodyfikowany).
W przypadku żądań CheckConditionalUpdate PUT, POST i DELETE przyjmuje bieżącą wartość elementu ETag zasobu. Jeśli bieżąca wartość ETag ma wartość null, metoda sprawdza, czy nagłówek If-None- Match ma wartość "*". Jeśli bieżąca wartość elementu ETag nie jest wartością domyślną, metoda sprawdza bieżącą wartość elementu ETag względem nagłówka If- Match żądania. W obu przypadkach metoda zgłasza WebFaultException kod stanu HTTP 412 (Warunek wstępny nie powiodło się), jeśli oczekiwany nagłówek nie znajduje się w żądaniu lub jego wartość nie spełnia warunków sprawdzania warunkowego i ustawia nagłówek ETag odpowiedzi na bieżącą wartość elementu ETag.
CheckConditional
Zarówno metody, jak i SetETag metoda zapewniają, że wartość elementu ETag ustawiona w nagłówku odpowiedzi jest prawidłowym elementem ETag zgodnie ze specyfikacją HTTP. Obejmuje to otaczanie wartości ETag w cudzysłowach podwójnych, jeśli nie są one jeszcze obecne i prawidłowo ucieczki od wewnętrznych znaków podwójnego cudzysłowu. Porównanie słabego elementu ETag nie jest obsługiwane.
W poniższym przykładzie pokazano, jak używać tych metod.
[WebGet(UriTemplate = "{id}"), Description("Returns the specified customer from customers collection. Returns NotFound if there is no such customer. Supports conditional GET.")]
public Customer GetCustomer(string id)
{
lock (writeLock)
{
// return NotFound if there is no item with the specified id.
object itemEtag = customerEtags[id];
if (itemEtag == null)
{
throw new WebFaultException(HttpStatusCode.NotFound);
}
// return NotModified if the client did a conditional GET and the customer item has not changed
// since when the client last retrieved it
WebOperationContext.Current.IncomingRequest.CheckConditionalRetrieve((long)itemEtag);
Customer result = this.customers[id] as Customer;
// set the customer etag before returning the result
WebOperationContext.Current.OutgoingResponse.SetETag((long)itemEtag);
return result;
}
}
Zagadnienia związane z zabezpieczeniami
Żądania wymagające autoryzacji nie powinny mieć buforowanych odpowiedzi, ponieważ autoryzacja nie jest wykonywana, gdy odpowiedź jest obsługiwana z pamięci podręcznej. Buforowanie takich odpowiedzi spowodowałoby poważną lukę w zabezpieczeniach. Zwykle żądania wymagające autoryzacji zapewniają dane specyficzne dla użytkownika i dlatego buforowanie po stronie serwera nie jest nawet korzystne. W takich sytuacjach buforowanie po stronie klienta lub po prostu nie buforowanie w ogóle jest bardziej odpowiednie.