2013-01-06 16 views
5

Da quello che posso vedere io devo creare un tipo di dati "speciale" per ogni tipo di dati che voglio trasferire su WCF, quindi se ho una classe condivisa comeUtilizzare un tipo di dati condivisa come DataContract in WCF

public class District 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
} 

e voglio inviare un oggetto District utilizza WCF, devo creare un DataContract e quindi devo creare una nuova classe WCF

[DataContract] 
public class WCFDistrict 
{ 
    [DataMember] 
    public long Id { get; set; } 

    [DataMember] 
    public string Name { get; set; } 
} 

e poi quando lo uso in un servizio WCF in mia implementazione I devono analizzare i dati da un oggetto all'altro

public WCFDistrict GetDistrict(long id) 
{ 
    var district = _districtRepository.GetDistrict(id); 
    return new WCFDistrict {Id = district.Id, Name = district.Name}; 
} 

C'è qualche modo per riutilizzare semplicemente la classe condivisa come DataContract, senza avere quegli attributi su di esso? O dovrei creare un'interfaccia sulle classi che possono condividere, quindi posso semplicemente lanciarla tra di loro? O qualcosa di terzo?

risposta

9

In primo luogo, non è strettamente necessario fornire un DataContract; WCF eseguirà la serializzazione di Plain Old Class Objects (POCO) correttamente finché si è su .Net 3.5 SP1 o versioni successive.

In secondo luogo, è possibile condividere lo stesso file di classe fisica nei progetti sia lato server che lato client; abbiamo progetti che hanno centinaia di classi (e codice) che sono condivisi direttamente in questo modo e risparmiano una quantità enorme di tempo e sforzi nello sviluppo e nei test.

ci sono un paio di passaggi necessari per ottenere questo installato e funzionante (facendo questo dalla memoria così posso avere bisogno regolare la risposta):

1) Nel lato client, se si utilizza VB, creare un progetto nello stesso spazio dei nomi predefinito delle classi che si desidera utilizzare nel lato client (per C#, questo non è importante poiché lo spazio dei nomi è incorporato nelle classi).

2) Aggiungere i file di classe al progetto come collegamenti in modo da disporre di una copia fisica della classe.

3) Aggiungere un dataContractSerializer alla configurazione WCF se non ne è già uno.

4) Sul lato client, fare clic con il pulsante destro del mouse sul servizio e scegliere Configura riferimento servizio ... Nella finestra di dialogo visualizzata, verificare che sia selezionato Reuse types in all referenced assemblies e che sia selezionata l'opzione Reuse types in all referenced assemblies.

5) La parte più difficile per ottenere questo funzionamento è per le raccolte.

a) Decorare la collezione con l'attributo CollectionDataContract.

b) Aggiungere una voce per questa raccolta alla tabella reference.svcmap di CollectionMappings. Per trovare il reference.svcmap, mostra tutti i file nel progetto e quindi espandi il servizio. Per modificarlo, fai doppio clic sul file.Aggiungere una voce qui per ogni raccolta specifica che si sta serializzando ed è necessario distinguere tra quegli elementi che hanno una base <> Elenco e quelli che hanno un dizionario <> base. Se non esegui questo passaggio, WCF serializzerà automaticamente queste classi alla firma generica sottostante e perderai l'uso delle tue classi.

Le voci in questa tabella simile a questa:

<CollectionMappings> 
    <CollectionMapping TypeName="System.Collections.Generic.Dictionary`2" Category="Dictionary" /> 
    <CollectionMapping TypeName="System.Collections.Generic.List`1" Category="List" /> 
    <CollectionMapping TypeName="System.Collections.Specialized.StringCollection" Category="List" /> 
    <CollectionMapping TypeName="My.Namespace.MyDictionaryCollection" Category="Dictionary" /> 

Quando si aggiungono queste voci e salvare il file, il generatore sul lato client WCF ricostruirà Reference.cs o il file Reference.vb seconda che lingua stai usando È possibile sapere se i riferimenti non sono configurati correttamente osservando il codice generato: se tale codice contiene definizioni di classe, il generatore di codice WCF non è stato in grado di eseguire il mapping delle classi copiate per qualche motivo.

Un'ultima nota: a volte il generatore di codice WCF non riesce a generare il codice e questo è sempre dovuto a un problema nel servizio (di solito una classe non è abbastanza unica o un tipo non è stato serializzabile per una motivo o altro).

Per eseguire il debug di questo tipo di problema, la cosa più semplice da fare è aggiungere la registrazione diagnostica WCF, che genererà un file che può essere aperto da uno strumento speciale (dimenticare il nome) che consente di eseguire il drill in i messaggi di errore e scoprire esattamente cosa è andato storto. Questo ci ha risparmiato un numero incalcolabile di ore di lavoro. Per configurare questa registrazione, aggiungere il seguente al vostro web.config ovunque nella sezione <configuration>:

<system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel" 
       switchValue="Information, ActivityTracing" 
       propagateActivity="true"> 
     <listeners> 
      <add name="traceListener" 
       type="System.Diagnostics.XmlWriterTraceListener" 
       initializeData="c:\log\WcfTrace.svclog" /> 
     </listeners> 
     </source> 
    </sources> 
    </system.diagnostics> 

Una volta aggiunto questo e web.config, salvato tentativo di aggiornare il riferimento al servizio nel client, quindi fare doppio fare clic sul file di registro specificato e lo strumento si aprirà.

4

Avrete bisogno di quegli attributi. Per semplificarti la vita, puoi utilizzare uno strumento come AutoMapper per eseguire il cablaggio degli oggetti di trasferimento dati poiché l'impostazione manuale di tutte le proprietà può essere noiosa.

È comunque buona norma mantenere le classi del modello separate dai contratti di dati in modo che le modifiche al modello non influiscano direttamente sui contratti di dati.

Problemi correlati