Domanda

Ho un contratto di servizio che definisce un metodo con un parametro di tipo System.Object (xs:anyType nel WSDL).Voglio essere in grado di passare tipi semplici e tipi complessi in questo parametro.I tipi semplici funzionano bene, ma quando provo a passare un tipo complesso definito nel mio WSDL, ottengo questo errore:

Elemento 'http://tempuri.org/:valore' contiene i dati del 'http://schemas.datacontract.org/2004/07/MyNamespace:MyClass' contratto dati.Il deserializzatore non è a conoscenza di alcun tipo associato a questo contratto.Aggiungere il tipo corrispondente a "MyClass" all'elenco dei tipi conosciuti, ad esempio utilizzando l'attributo KnownTypeAttribute o aggiungendolo all'elenco dei tipi conosciuti passati a DataContractSerializer.

Aggiungerlo come tipo noto non aiuta perché è già nel mio WSDL.Come posso passare un oggetto di tipo complesso tramite un parametro "xs:anyType"?

Ulteriori informazioni:

Credo che funzioni quando si utilizza NetDataContract, ma non posso utilizzarlo perché il mio cliente è Silverlight.

Ho visto riferimenti a tipi complessi che estendono esplicitamente xs:anyType, ma non ho idea di come fare in modo che WCF generi un WSDL che lo faccia e non ho idea se sarebbe d'aiuto o meno.

Grazie

È stato utile?

Soluzione 3

Ho risolto questo problema utilizzando l'attributo ServiceKnownType.Aggiungo semplicemente il mio tipo complesso come tipo noto del servizio nel mio contratto di servizio e l'errore scompare.Non sono sicuro del motivo per cui non ha funzionato l'ultima volta che l'ho provato.

Non sembra influenzare in alcun modo il WSDL, quindi sospetto che il flusso serializzato debba presentare qualche differenza che informi il deserializzatore che l'oggetto può essere deserializzato utilizzando il mio tipo.

Altri suggerimenti

NetDataContract funziona perché NetDataContractSerializer include informazioni sul tipo.

L'attributo KnownType indica a DataContractSerializer come deserializzare il messaggio.Essendo specifiche dell'implementazione, si tratta di informazioni che vanno oltre quelle definite dal contratto pubblico e non appartengono al WSDL.

Non sarai mai in grado di passare alcun vecchio tipo di dati perché il deserializzatore deve identificare il tipo appropriato e creare un'istanza.

Potresti essere in grado di derivare i tipi noti in fase di esecuzione anziché codificarli nel DataContract.Guarda Qui per un campione.

Spero che questo possa essere d'aiuto.Ho visto un mio collega utilizzare questo codice per inviare tipi di dati complicati e per me è piuttosto semplice.Questo è stato utilizzato con basicHttpBinding e funziona abbastanza bene con MOSS BDC e con altre applicazioni che utilizzano l'associazione di base.

  1. Creare un contratto dati basato su una classe generica
  2. Utilizzare il contratto dati quando è necessario inviare le informazioni

    [DataContract(Spazio dei nomi = "http://Service.DataContracts", Name =" serviceAtaContractBase ")] classe pubblica ServiceAtaContract {

    public ServiceDataContract() { }
    
    public ServiceDataContract(TValueType Value)
    {
        this.m_objValue = Value;
    }
    
    private TValueType m_objValue;
    
    [DataMember(IsRequired = true, Name = "Value", Order = 1)]
    public TValueType Value
    {
        get { return m_objValue; }
        set { m_objValue = value; }
    }
    

    }

Utilizzare questo contratto dati ovunque sia necessario nelle funzioni WCF che restituiscono il tipo di dati complicato.Per esempio:

public ServiceDataContract<string[]> GetStrings()
{
    string[] temp = new string[10];
    return new ServiceDataContract<string[]>(temp);
}

Aggiornamento:ServiceDataContract è una classe generica che utilizza TValueType.Non viene visualizzato a causa di qualcosa di sbagliato nel rendering dell'HTML.

Prova a utilizzare i surrogati del contratto dati per mappare oggetti non supportati che sono tipi specifici di dot net o non interoperabili.Vedere MSDN

Per ora ho risolto questo problema creando un nuovo tipo di contratto dati che può racchiudere un altro tipo di contratto dati o un tipo semplice.Invece di passare il tipo Object, ora passo questa classe wrapper.Funziona bene, ma mi piacerebbe comunque sapere se esiste una soluzione al problema originale.

Ho provato ad aggiungere l'attributo ServiceKnownType, specificando il tipo che sto cercando di passare, ma ricevo ancora lo stesso errore. Ho anche provato ad aggiungere l'attributo KnownType al mio contratto dati (il che sembrava sciocco perché era dello stesso tipo del contratto dati).Immagino che aggiungerli in fase di esecuzione non sia d'aiuto se aggiungerli in fase di compilazione non aiuta.

Se dovessi estendere un altro tipo complesso, mi sembra che vorrei aggiungere l'attributo KnownType a quel tipo di base.Ma poiché il mio tipo di base è Object, non vedo alcun modo per farlo.

Per quanto riguarda i Surrogati, mi sembra che questi servano per tipologie di confezionamento che non hanno un contratto definito.Nel mio caso, tuttavia, ho definito il contratto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top