Condividi tramite


Gestione del contesto del servizio dati (WCF Data Services)

La classe DataServiceContext incapsula operazioni supportate su un servizio dati specificato. Sebbene i servizi OData siano senza stato, non lo è il contesto. È pertanto possibile utilizzare la classe DataServiceContext per mantenere lo stato nel client tra le interazioni con il servizio dati in modo da supportare funzionalità quali la gestione di modifiche. Questa classe consente inoltre di gestire le identità e di rilevare le modifiche.

Risoluzione di identità e opzioni di unione

Quando viene eseguito un oggetto DataServiceQuery<TElement>, le entità nel feed di risposta vengono materializzate in oggetti. Per ulteriori informazioni, vedere Materializzazione di oggetti (WCF Data Services). La modalità di materializzazione in oggetti delle voci presenti in un messaggio di risposta si basa sulla risoluzione di identità e dipende dall'opzione di unione con cui è stata eseguita la query. Quando più query o richieste di caricamento vengono eseguite nell'ambito di un solo DataServiceContext, il client WCF Data Services rileva solo un'istanza di un oggetto con un valore della chiave specifico. Questa chiave, utilizzata per eseguire la risoluzione di identità, identifica in modo univoco un'entità.

Per impostazione predefinita, il client materializza una sola voce del feed di risposta in un oggetto delle entità non ancora rilevate da DataServiceContext. In altre parole, non vengono sovrascritte le modifiche agli oggetti già presenti nella cache. Questo comportamento viene controllato specificando un valore MergeOption per le query e le operazioni di caricamento. Questa opzione viene specificata impostando la proprietà MergeOption su DataServiceContext. Il valore dell'opzione di unione predefinita è AppendOnly. Questo valore consente di materializzare gli oggetti delle entità non ancora rilevate. Ciò significa che gli oggetti esistenti non vengono sovrascritti. Un'altra modalità per impedire che gli oggetti sul client vengano sovrascritti dagli aggiornamenti del servizio dati consiste nello specificare PreserveChanges. Quando si specifica OverwriteChanges, i valori degli oggetti nel client vengono sostituiti dai valori più recenti delle voci presenti nel feed di risposta, anche se a tali oggetti sono già state apportate modifiche. Quando viene utilizzata un'opzione di unione NoTracking, DataServiceContext non può inviare al servizio dati le modifiche apportate agli oggetti del client. Con questa opzione le modifiche vengono sempre sovrascritte dai valori del servizio dati.

Gestione della concorrenza

OData supporta la concorrenza ottimistica che consente al servizio dati il rilevamento dei conflitti di aggiornamento. È possibile configurare il provider del servizio dati in modo che il servizio dati verifichi le modifiche alle entità tramite un token di concorrenza. Il token è costituito da una o più proprietà di un tipo di entità che vengono convalidate dal servizio dati per determinare se una risorsa è stata modificata. I token di concorrenza inclusi nell'intestazione eTag delle richieste al servizio dati e delle relative risposte vengono gestiti automaticamente dal client WCF Data Services. Per ulteriori informazioni, vedere Aggiornamento del servizio dati (WCF Data Services).

DataServiceContext rileva le modifiche apportate agli oggetti segnalati manualmente tramite AddObject, UpdateObject e DeleteObject o tramite un oggetto DataServiceCollection<T>. Quando si chiama il metodo SaveChanges, il client restituisce le modifiche al servizio dati. Quando le modifiche del client sono in conflitto con quelle del servizio dati, è possibile che l'esecuzione del metodo SaveChanges non riesca. Quando si verifica ciò, è necessario eseguire una nuova query per la risorsa dell'entità per ricevere i dati dell'aggiornamento. Per sovrascrivere le modifiche nel servizio dati, eseguire la query utilizzando l'opzione di unione PreserveChanges. Quando si chiama nuovamente SaveChanges, le modifiche salvate sul client vengono salvate in modo permanente nel servizio dati e rimangono in tale posizione fino a quando le altre modifiche non vengono apportate alla risorsa nel servizio dati.

Salvataggio delle modifiche

Le modifiche vengono rilevate nell'istanza di DataServiceContext, ma non vengono inviate immediatamente al server. Dopo aver apportato le modifiche necessarie per un'attività specificata, chiamare SaveChanges per inviare tutte le modifiche al servizio dati. Un oggetto DataServiceResponse verrà restituito al complemento dell'operazione SaveChanges. L'oggetto DataServiceResponse include una sequenza di oggetti OperationResponse che a loro volta contengono una sequenza di istanze di EntityDescriptor o LinkDescriptor che rappresentano le modifiche persistenti o tentate. Quando un'entità viene creata o modificata nel servizio dati, in EntityDescriptor è presente un riferimento all'entità aggiornata, inclusi i valori di proprietà generati dal server, ad esempio il valore ProductID generato nell'esempio precedente. Nella libreria client l'oggetto .NET Framework viene aggiornato automaticamente in modo da impostare i nuovi valori.

Per le operazioni di inserimento e aggiornamento completate correttamente, la proprietà di stato dell'oggetto EntityDescriptor o LinkDescriptor associato all'operazione viene impostata su Unchanged e i nuovi valori vengono uniti tramite OverwriteChanges.

Quando un'operazione di inserimento, aggiornamento o eliminazione non riesce nel servizio dati, lo stato dell'entità rimane invariato rispetto a prima della chiamata del metodo SaveChanges e la proprietà Error di OperationResponse viene impostata su un oggetto DataServiceRequestException contenente le informazioni sull'errore. Per ulteriori informazioni, vedere Aggiornamento del servizio dati (WCF Data Services).

Gestione delle richieste

Il protocollo OData fornisce la flessibilità dei comportamenti delle richieste a un servizio dati e delle risposte allo stesso. La libreria client consente di sfruttare questa flessibilità controllando il modo in cui l'applicazione interagisce con il servizio dati.

Impostazione dell'intestazione Prefer per le operazioni di modifica

Per impostazione predefinita, un payload del messaggio viene restituito solo in risposta a una richiesta POST per creare una nuova entità. In questo caso, la nuova entità viene restituita nel payload. Ciò significa che quando vengono eseguiti gli aggiornamenti agli oggetti, l'entità aggiornata non viene restituita nel payload o nel messaggio di risposta. Tuttavia, il protocollo OData dichiara che un client può utilizzare l'intestazione Prefer per richiedere una modifica rispetto a questo comportamento predefinito. L'intestazione Prefer in una richiesta POST, PUT, PATCH o MERGE viene generata dall'oggetto DataServiceContext in base al valore dell'oggetto DataServiceResponsePreference impostato nella proprietà AddAndUpdateResponsePreference. Nella tabella seguente vengono mostrate le opzioni dell'intestazione Prefer e i comportamenti della risposta correlati:

Valore dell'intestazione Prefer

Valore di AddAndUpdateResponsePreference

Comportamento della risposta

Non incluso nella richiesta. Questo è il comportamento predefinito.

None

Un payload della risposta viene restituito solo per le richieste POST e non per le richieste PUT, PATCH e MERGE.

return-content

IncludeContent

Un payload della risposta viene restituito per tutte le richieste di modifica.

return-no-content

NoContent

Non viene restituito alcun payload della risposta per le richieste. Per una richiesta POST il servizio dati include anche un'intestazione DataServiceId nella risposta. Questa intestazione viene utilizzata per comunicare il valore chiave dell'entità appena creata.

Nota

Anche quando il servizio dati supporta una versione del protocollo OData che supporta l'intestazione Prefer, un servizio dati può scegliere di non rispettare questi tipi di preferenze dell'elaborazione delle richieste.

Impostazione del metodo HTTP per gli aggiornamenti

Per impostazione predefinita, la libreria client .NET Framework invia aggiornamenti alle entità esistenti come richieste MERGE. In OData una richiesta MERGE aggiorna le proprietà selezionate dell'entità. Il client tuttavia include sempre tutte le proprietà nella richiesta MERGE, anche le proprietà che non sono modificate. Il protocollo OData supporta anche l'invio delle richieste PUT e PATCH per aggiornare le entità. In una richiesta PUT, un'entità esistente viene essenzialmente sostituita con una nuova istanza dell'entità con i valori della proprietà dal client. Le richieste PATCH vengono gestite nella stesso modo delle richieste MERGE. Tuttavia, PATCH è un'azione HTTP standard, mentre MERGE viene definita da OData. Questo comportamento di aggiornamento viene specificato fornendo come opzioni il valore ReplaceOnUpdate, per utilizzare le richieste PUT, o il valore PatchOnUpdate, per utilizzare le richieste PATCH, quando viene chiamato SaveChanges(SaveChangesOptions).

Nota

Una richiesta PUT si comporterà in modo diverso da una richiesta MERGE o PATCH se il client non conosce tutte le proprietà dell'entità.Questo potrebbe verificarsi quando si proietta un tipo di entità in un nuovo tipo sul client.Si potrebbe verificare anche quando nuove proprietà sono state aggiunte all'entità nel modello di dati del servizio e la proprietà IgnoreMissingProperties di DataServiceContext è impostata su true per ignorare tali errori del mapping client.In questi casi, una richiesta PUT reimposterà qualsiasi proprietà sconosciuta al client sui valori predefiniti.

POST tunneling

Per impostazione predefinita, la libreria client invia richieste di creazione, lettura, aggiornamento ed eliminazione a un servizio OData tramite i metodi HTTP corrispondenti di POST, GET, PUT/MERGE/PATCH e DELETE. In questo modo vengono conservati i principi di base di REST (Representational State Transfer). Tuttavia, non tutte le implementazioni del server Web supportano il set completo di metodi HTTP. In alcuni casi, i metodi supportati potrebbero essere limitati solo a GET e POST. Ciò può verificarsi quando un intermediario, ad esempio un firewall, blocca le richieste con alcuni metodi. Poiché i metodi GET e POST sono quelli supportati più frequentemente, OData stabilisce una modalità per eseguire tutti i metodi HTTP non supportati tramite una richiesta POST. Noto come metodo tunneling o POST tunneling, esso consente a un client di inviare una richiesta POST con il metodo effettivo specificato nell'intestazione X-HTTP-Method personalizzata. Per abilitare il POST tunneling per le richieste, impostare la proprietà UsePostTunneling nell'istanza DataServiceContext su true.

Risoluzione dell'URI di base dei set di entità

Per impostazione predefinita, il client presuppone che tutti i set di entità, noti anche come raccolte, condividano lo stesso URI di base. Questo URI di base viene definito dalla proprietà BaseUri nell'oggetto DataServiceContext. Tuttavia, il protocollo OData consente a un servizio dati di esporre i set di entità come feed che contengono URI di base diversi. Per poter gestire set di entità con URI di base diversi, il client consente di registrare un delegato con l'oggetto DataServiceContext che può essere utilizzato per risolvere gli URI di base di vari set di entità. Questo delegato è un metodo che accetta una stringa (il nome del set di entità) e restituisce un oggetto Uri (l'URI di base per il set di entità specificato). Questa risoluzione viene registrata con l'oggetto DataServiceContext dall'assegnazione alla proprietà ResolveEntitySet. Un esempio di implementazione della risoluzione potrebbe leggere le informazioni su raccolte restituite dalla radice del servizio dati e archiviare i valori degli URI di base per ogni raccolta presente in un dizionario nel momento in cui viene creato il contesto. Questo dizionario potrebbe quindi essere utilizzato dalla risoluzione per restituire l'URI per un set di entità specifico. Per un esempio più esaustivo, incluso il codice di esempio, vedere il post Risoluzione dei set di entità.

Requisiti di versione

I comportamenti di DataServiceContext prevedono i seguenti requisiti di versione del protocollo OData:

  • Il sopporto dell'intestazione Prefer e delle richieste PATCH richiede che il client e il servizio dati supportino entrambi la versione 3.0 del protocollo OData e versioni successive.

  • Il supporto delle risoluzioni del set di entità richiede la versione della libreria client di WCF Data Services inclusa con la versione di Data Framework o una versione successiva.

Per ulteriori informazioni, vedere Controllo delle versioni del servizio dati (WCF Data Services).