Stöd för cachelagring för WCF-webb-HTTP-tjänster
Med .NET Framework 4.6.1 kan du använda den deklarativa cachelagringsmekanismen som redan är tillgänglig i ASP.NET i dina WCF Web HTTP-tjänster. Med den här mekanismen kan du cachelagras svar från WCF Web HTTP-tjänståtgärder. När en användare skickar en HTTP GET
till din tjänst som har konfigurerats för cachelagring skickar ASP.NET tillbaka det cachelagrade svaret och tjänstmetoden anropas inte. När cachen upphör att gälla anropas din tjänstmetod nästa gång en användare skickar och HTTP GET
svaret cachelagras igen. Mer information om ASP.NET cachelagring finns i ASP.NET Översikt över cachelagring.
Grundläggande cachelagring av webb-HTTP-tjänsten
Om du vill aktivera CACHElagring av WEB HTTP-tjänsten måste du först aktivera ASP.NET kompatibilitet genom att tillämpa AspNetCompatibilityRequirementsAttribute på tjänstinställningen RequirementsMode på Allowed eller Required.
.NET Framework 4 introducerar ett nytt attribut med namnet AspNetCacheProfileAttribute som gör att du kan ange ett namn på cacheprofilen. Det här attributet tillämpas på en tjänståtgärd. Följande exempel gäller AspNetCompatibilityRequirementsAttribute för en tjänst för att aktivera ASP.NET kompatibilitet och konfigurerar GetCustomer
åtgärden för cachelagring. Attributet AspNetCacheProfileAttribute anger en cacheprofil som innehåller de cacheinställningar som ska användas.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
[WebGet(UriTemplate = "{id}")]
[AspNetCacheProfile("CacheFor60Seconds")]
public Customer GetCustomer(string id)
{
// ...
}
}
Aktivera också ASP.NET kompatibilitetsläge i filen Web.config enligt följande exempel.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Varning
Om ASP.NET kompatibilitetsläge inte är aktiverat och AspNetCacheProfileAttribute används genereras ett undantag.
Namnet på cacheprofilen AspNetCacheProfileAttribute som anges av identifierar en cacheprofil som läggs till i konfigurationsfilen web.config. Cacheprofilen definieras med i ett <outputCacheSetting>
element enligt följande konfigurationsexempel.
<!-- ... -->
<system.web>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor60Seconds" duration="60" varyByParam="none" sqlDependency="MyTestDatabase:MyTable"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<!-- ... -->
</system.web>
Det här är samma konfigurationselement som är tillgängligt för ASP.NET program. Mer information om ASP.NET cacheprofiler finns i OutputCacheProfile. För HTTP-webbtjänster är de viktigaste attributen i cacheprofilen: cacheDuration
och varyByParam
. Båda dessa attribut krävs. cacheDuration
anger hur lång tid ett svar ska cachelagras i sekunder. varyByParam
gör att du kan ange en frågesträngsparameter som används för att cachelagrar svar. Alla begäranden som görs med olika frågesträngsparametervärden cachelagras separat. När till exempel en första begäran görs till http://MyServer/MyHttpService/MyOperation?param=10
returneras alla efterföljande begäranden som görs med samma URI det cachelagrade svaret (så länge cachevaraktigheten inte har förflutit). Svar för en liknande begäran som är densamma men som har ett annat värde för parametern frågesträngsparameter cachelagras separat. Om du inte vill ha det här separata cachelagringsbeteendet anger du varyByParam
"ingen".
SQL Cache-beroende
Webb-HTTP-tjänstsvar kan också cachelagras med ett SQL-cacheberoende. Om WCF Web HTTP-tjänsten är beroende av data som lagras i en SQL-databas kanske du vill cachelagra tjänstens svar och ogiltigförklara det cachelagrade svaret när data i SQL-databastabellen ändras. Det här beteendet har konfigurerats helt i filen Web.config. Definiera först en anslutningssträng i elementet<connectionStrings>
.
<connectionStrings>
<add name="connectString"
connectionString="..."
providerName="System.Data.SqlClient" />
</connectionStrings>
Aktivera sedan SQL-cacheberoende i ett <caching>
element i -elementet <system.web>
enligt följande konfigurationsexempel.
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="1000">
<databases>
<add name="MyTestDatabase" connectionStringName="connectString" />
</databases>
</sqlCacheDependency>
<!-- ... -->
</caching>
<!-- ... -->
</system.web>
Här aktiveras SQL-cacheberoende och en avsökningstid på 1 000 millisekunder anges. Varje gång avsökningstiden förflutit kontrolleras databastabellen efter uppdateringar. Om ändringar upptäcks tas innehållet i cacheminnet bort och nästa gång tjänståtgärden anropas cachelagras ett nytt svar. I elementet <sqlCacheDependency>
lägger du till databaserna och refererar till anslutningssträng i elementet <databases>
enligt följande exempel.
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="1000">
<databases>
<add name="MyTestDatabase" connectionStringName="connectString" />
</databases>
</sqlCacheDependency>
<!-- ... -->
</caching>
<!-- ... -->
</system.web>
Därefter måste du konfigurera cacheinställningarna för utdata i elementet <caching>
enligt följande exempel.
<system.web>
<caching>
<!-- ... -->
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor60Seconds" duration="60" varyByParam="none" sqlDependency="MyTestDatabase:MyTable" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<!-- ... -->
</system.web>
Här är cachevaraktigheten inställd på 60 sekunder, varyByParam
är inställd på ingen och sqlDependency
är inställd på en semikolonavgränsad lista över databasnamn/tabellpar avgränsade med kolon. När data i MyTable
ändras tas det cachelagrade svaret för tjänståtgärden bort och när åtgärden anropas genereras ett nytt svar (genom att anropa tjänståtgärden), cachelagras och returneras till klienten.
Viktigt!
För att ASP.NET ska få åtkomst till en SQL-databas måste du använda registreringsverktyget för ASP.NET SQL Server. Dessutom måste du tillåta lämplig användarkontoåtkomst till databasen och tabellen. Mer information finns i Komma åt SQL Server från ett webbprogram.
Villkorlig HTTP GET-baserad cachelagring
I WEBB-HTTP-scenarier används en villkorsstyrd HTTP GET ofta av tjänster för att implementera intelligent HTTP-cachelagring enligt beskrivningen i HTTP-specifikationen. För att göra detta måste tjänsten ange värdet för ETag-huvudet i HTTP-svaret. Den måste också kontrollera rubriken If-None-Match i HTTP-begäran för att se om någon av de angivna ETag-objekten matchar den aktuella ETag-filen.
För GET- och HEAD-begäranden CheckConditionalRetrieve tar du ett ETag-värde och kontrollerar det mot rubriken If-None-Match i begäran. Om rubriken finns och det finns en matchning genereras en WebFaultException med HTTP-statuskoden 304 (inte ändrad) och en ETag-rubrik läggs till i svaret med matchande ETag.
En överlagring av CheckConditionalRetrieve metoden tar ett senast ändrat datum och kontrollerar det mot rubriken If-Modified-Since i begäran. Om rubriken finns och resursen inte har ändrats sedan dess genereras en WebFaultException med HTTP-statuskod 304 (inte ändrad).
För PUT-, POST- och DELETE-begäranden CheckConditionalUpdate tar det aktuella ETag-värdet för en resurs. Om det aktuella ETag-värdet är null kontrollerar metoden att rubriken If-None- Match har värdet "*". Om det aktuella ETag-värdet inte är ett standardvärde kontrollerar metoden det aktuella ETag-värdet mot if-match-huvudet för begäran. I båda fallen genererar metoden en WebFaultException med HTTP-statuskoden 412 (villkorsfel misslyckades) om det förväntade huvudet inte finns i begäran eller om dess värde inte uppfyller den villkorsstyrda kontrollen och anger ETag-huvudet för svaret till det aktuella ETag-värdet.
CheckConditional
Både metoderna och SetETag metoden säkerställer att ETag-värdet som anges i svarshuvudet är en giltig ETag enligt HTTP-specifikationen. Detta inkluderar att omge ETag-värdet med dubbla citattecken om de inte redan finns och på rätt sätt undfly eventuella interna dubbla citattecken. Svag ETag-jämförelse stöds inte.
I följande exempel visas hur du använder dessa metoder.
[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;
}
}
Säkerhetsöverväganden
Begäranden som kräver auktorisering bör inte ha sina svar cachelagrade, eftersom auktoriseringen inte utförs när svaret hanteras från cachen. Cachelagring av sådana svar skulle medföra en allvarlig säkerhetsrisk. Vanligtvis är begäranden som kräver auktorisering användarspecifika data och därför är cachelagring på serversidan inte ens fördelaktigt. I sådana situationer är cachelagring på klientsidan eller helt enkelt inte cachelagring alls lämpligare.