2016-01-28 29 views
5

Sto provando a creare un'applicazione WCF che ascolterà le richieste da un sistema di fornitori. Il fornitore mi ha fornito un WSDL, quindi ho bisogno di creare un servizio ed esporre il suo endpoint ad essi.Servizio WCF + SvcUtil generando una struttura di oggetto inattesa

Ho usato SvcUtil.exe per generare le classi C#, ma emette tipi piuttosto bizzarri.

Si tratta di un frammento del WSDL che è stato dato a me:

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 
    <wsdl:types> 
    <s:schema elementFormDefault="qualified"> 
     <s:element name="Submit"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="Incident"> 
       <s:complexType> 
       <s:sequence> 
        <s:element minOccurs="0" maxOccurs="1" form="unqualified" name="TransactionId" type="s:string" /> 
        <s:element minOccurs="0" maxOccurs="1" form="unqualified" name="TransactionType" type="s:string" /> 
        <s:element minOccurs="0" maxOccurs="1" form="unqualified" name="TransactionSubType" type="s:string" /> 
        <s:element minOccurs="0" maxOccurs="unbounded" form="unqualified" name="ConfigurationItem"> 
        <s:complexType> 
         <s:sequence> 
         <s:element minOccurs="0" maxOccurs="1" form="unqualified" name="AssetTag" type="s:string" /> 
         <s:element minOccurs="0" maxOccurs="1" form="unqualified" name="Name" type="s:string" /> 
        .... 

Il comando corro è semplicemente

svcutil.exe file_name.wsdl 

Mi aspetterei che questo crea una struttura come questa:

class Submit { ... } 
class Incident { ... } 
class ConfigurationItem { ... } 

In modo che quando viene serializzato ottengo qualcosa di simile:

<Submit> 
    <Incident> 
     <TransactionId>12345</TransactionId> 
     <TransactionType>12345</TransactionType> 
     <TransactionSubType>12345</TransactionSubType> 
     <ConfigurationItem> 
      <AssetTag>xyz</AssetTag> 
      <Name>name</Name> 
     </ConfigurationItem> 
    </Incident> 
</Submit> 

Tuttavia, l'uscita del SvcUtil.exe mi dà il seguente:

class SubmitIncident { ... } 
class SubmitIncidentConfigurationItem { ... } 

E 'sembra grappolo Submit e l'incidente oggetti in uno, ed inoltre antepone 'SubmitIncident' su ciascuno dei gli elementi nidificati Così, quando la serializzazione ottengo questo:

<SubmitIncident> 
    <TransactionId>...</TransactionId> 
    <TransactionType>...</TransactionType> 
    <TransactionSubType>...</TransactionSubType> 
    <SubmitIncidentConfigurationItem> 
     <AssetTag>...</AssetTag> 
     <Name>...</Name> 
    </SubmitIncidentConfigurationItem> 
</SubmitIncident> 

Questo provoca problemi sia con il fornitore (il mio servizio non corrisponde a loro WSDL quindi non possono parlare con me), e con l'elaborazione in poi sto facendo nella domanda . Qualcuno può aiutarmi a capire perché questo sta accadendo, come fermarlo e far sì che SvcUtil sia emesso correttamente.

risposta

1

Si scopre che le definizioni e le definizioni di classe non sono realmente il problema qui (causerà un altro problema in seguito ma è facilmente risolvibile anche una volta capito cosa sta succedendo). Il problema era radicato in qualcosa che avevo fatto nella fase di sviluppo del throwaway.

La prima cosa che ho fatto è stata utilizzare svcutil.exe per generare le classi del server utilizzando WSDL dal fornitore. Una volta avuta abbastanza per avviare il debug/test, naturalmente mi sono diretto verso il client di test di WCF e il server di sviluppo integrato di Visual Studio. Quando si utilizza il client, ha continuato a venire con tutti i tipi di errori oscuri, ad es. https non supportato, i problemi con i contratti e le associazioni, ecc Molti di loro sono stati incongruenze di configurazione in modo sono stati fissati con un po 'di usare Google, ma fra gli errori è stato questo:

The operation is not supported in the WCF Test Client because it uses type SubmitIncident

Questo succedeva quando uno dei SubmitIncident Le proprietà erano di tipo object (anche se nidificate più in basso in altre proprietà). Fondamentalmente stavo solo lavorando su un errore alla volta, estrapolando bit che non funzionavano fino a quando non lo facevano. Principalmente stavo aggiungendo e rimuovendo attributi su proprietà e classi, ad es. DataMember, SoapAction, Namespace, ecc.

Eventualmente è stato possibile richiamare correttamente gli endpoint dell'applicazione utilizzando il client di test WCF. Tuttavia, quando si trattava di altre applicazioni che comunicavano con esso, stava fallendo come da domanda originale. Le modifiche apportate per farlo funzionare nel client di test WCF hanno effettivamente reso il servizio non valido per lo schema WSDL originale!

TL; DR;

Non compilare le applicazioni WCF utilizzando il client di test WCF per testarle. Non posso sottolineare abbastanza questo. Ti costringe a rimuovere le cose che potrebbero causare l'interruzione della tua applicazione nell'uso normale. Utilizzare un'applicazione standard del settore come SoapUI anche dalla fase di sviluppo iniziale.

Link utili