2010-04-05 15 views
7

Ho un servizio Web .NET (usando ASMX ... non hanno aggiornato ad ancora WCF) che espone quanto segue:Perché non riesco a esporre un'interfaccia in un servizio Web asmx .NET?

public class WidgetVersion1 : IWidget {} 
public class WidgetVersion2 : IWidget {} 

quando tento di legarsi al servizio web, ottengo il seguente errore di serializzazione :

Impossibile serializzare membro WidgetVersion1 di tipo IWidget perché è un'interfaccia.

Ho provato ad aggiungere vari attributi all'interfaccia iWidget (XmlIgnore, SoapIgnore, NonSerialized), ma non sono validi su un'interfaccia.

Qualcuno sa perché non riesco a esporre l'interfaccia? Suppongo che WSDL non supporti le interfacce, ma .NET non potrebbe aggirare questo semplicemente non serializzando l'interfaccia? Ci sono modi per aggirare questo a parte la rimozione dell'interfaccia IWidget dalle definizioni di classe WidgetVersion1 e WidgetVersion2?

risposta

10

WCF non può serializzare un'interfaccia sia; infatti, è impossibile serializzare un'interfaccia su SOAP.

La ragione (semplificata) è che, quando deserializza, .NET deve essere in grado di creare una classe concreta effettiva. Un'interfaccia è un concetto astratto; deve esserci sempre un'implementazione di classe "reale" dietro di essa affinché esista un'istanza reale.

Poiché non è possibile creare un'istanza fisica di un'interfaccia, non è possibile serializzarla.

Se si sta tentando di utilizzare XmlIgnoreAttribute, capire che applicarlo al tipo non comporterà nulla. Deve essere applicato invece al membro membro. In altre parole:

public class SerializableClass 
{ 
    [XmlElement] 
    public int ID { get; set; } 

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

    [XmlIgnore] 
    public IMyInterface Intf { get; set; } 
} 

... sarà serializzare OK, perché il serializzatore non cercherà di serializzare la proprietà Intf. Non è possibile aggiungere l'attributo [XmlIgnore] alla definizione del tipo IMyInterface (non verrà compilato).

+0

Grazie per la chiara spiegazione; ha perfettamente senso. – mcliedtk

+0

Mi stavo chiedendo se fosse il caso e poi ho letto di nuovo la domanda e anche se stava cercando di usare una classe con un'interfaccia. – Joshua

2

Creare una funzione AsIWigit() che restituisce una classe bridge privata che implementa detta interfaccia.

Questo fornirà un modo per convertire queste classi nell'interfaccia appropriata secondo necessità e funzionerà con i servizi ASMX.

+0

+1 bella idea per aggirare questo – mcliedtk

Problemi correlati