2009-08-20 1 views
0

Ich habe einen C# .net 2.0 Webservice erstellt. Ich muss das rohe XML erfassen, das vom Client gesendet wurde, und es für eine XSD validieren und Fehler an den Client zurückgeben. Der Webservice ermöglicht dem Kunden, eine Liste von Widgets auf unser System hochzuladen.Webservices Design und Wie kann ich das Roh-XML erfassen, das an einen Webservice-Aufruf in C# .net gesendet wird, damit ich es gegen eine XSD validieren kann?

Nachfolgend einige Hintergrundinfos:

ich eine XSD erstellt einen „Widget“ zu modellieren, die ein komplexes Objekt ist. Es sieht ungefähr so ​​aus:

<xs:element name="WidgetList"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="Widget" maxOccurs="unbounded" type="WidgetType" /> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 
<xs:complexType name="WidgetType"> 
    <xs:sequence maxOccurs="1" minOccurs="1"> 
     <xs:element name="Seller" type="AccountType" maxOccurs="1" minOccurs="1" /> 
     <xs:element name="Buyer" type="AccountType" maxOccurs="1" minOccurs="1" /> 
    </xs:sequence> 
    <xs:attribute name="Market" type="MarketType" use="required" /> 
</xs:complexType> 
<!-- etc... --> 

Dann benutzte ich XSD.exe Klassen aus dem XSD zu erzeugen.
Die Klassen, die erstellt werden, sind WidgetList, Widget, Verkäufer, Käufer, usw.

Als nächstes habe ich eine Webservice-Methode das Hochladen zu nehmen. Es sieht so aus:

[WebMethod] 
[SoapHeader("SecurityAuthenticationHeader", Direction = SoapHeaderDirection.In)] 
public string UploadWidgets(WidgetList wl) 
{ 
    //Need to validate the XML against the XSD here. 

    //Code to import... 
} 

Zwei Fragen:

  1. Gibt es eine Möglichkeit, dass ich die XML-Rohdaten vom Client an meiner ursprünglichen XSD gesendet validieren kann?
  2. Ist etwas falsch mit der Art, wie ich diesen Service erstellt habe?

UPDATE:
Der Grund, warum ich dies tun müssen, ist, dass, obwohl die XSD sagt Felder erforderlich oder minOccurs = 1, so scheint es, dass diese Eigenschaften nicht in der WSDL erforderlich (Nicht wirklich sicher warum).

Dies ist, was Teil der WSDL sieht aus wie (entfernt unnötige Teile der Kürze halber):

<s:schema elementFormDefault="qualified" targetNamespace="http://www.clearpar.com/XMLSchema"> 
    <s:element name="lt"> 
    <s:complexType> 
     <s:sequence> 
     <s:element minOccurs="0" maxOccurs="unbounded" name="LoanTrade" type="s1:LoanTradeType" /> 
     </s:sequence> 
    </s:complexType> 
    </s:element> 
<s:complexType name="LoanTradeType"> 
    <s:sequence> 
    <s:element minOccurs="0" maxOccurs="1" name="Seller" type="s1:AccountType" /> 
    <s:element minOccurs="0" maxOccurs="1" name="Buyer" type="s1:AccountType" /> 
    </s:sequence> 
    <s:attribute name="Market" type="s1:MarketType" use="required" /> 
</s:complexType> 
<s:complexType name="AccountType"> 
    <s:attribute name="Name" type="s:string" /> 
    <s:attribute name="ClientSystemID" type="s:string" /> 
</s:complexType> 

Antwort

1

Ich glaube nicht, dass es eine einfache Möglichkeit, dies zu tun.

Es gibt eine MSDN article on implementing a SoapExtension für die Schema-Validierung. Dies ist die Route, die ich mit einigen Verbesserungen nahm.

Es ist bedauerlich, dass es keinen automatischen Mechanismus gibt, um gegen die WSDL zu validieren, besonders da der Dienst das Schema bereits kennt. Mich würde interessieren, ob sich diese Situation in WCF geändert hat: Ich portiere jetzt meine Dienste und würde es lieben, wenn sie dieses Problem eleganter gelöst hätten.

+1

Ich habe nicht gehört, dass es in WCF geändert wurde. Auch, BTW, ist es nicht korrekt zu sagen, dass der Dienst das Schema kennt. Bei ASMX-Diensten wird das Schema normalerweise aus den Service-Metadaten generiert, nicht umgekehrt. Der XML-Serializer erstellt dann basierend auf den gefundenen .NET-Typen den benötigten Code, indem er die Servicemetadaten reflektiert. Bislang ist keine XML-Manipulation beteiligt. Zur Laufzeit wird das Schema nicht einmal durch den generierten Serialisierungscode impliziert, der die meisten Facetten des Schemas ignoriert. –

0

Da Sie eine strengere Kontrolle über Ihre WSDL benötigen, empfehle ich, sie manuell zu schreiben und sowohl Ihre Servicevertragsschnittstelle/Daten/Nachrichten als auch Clientproxys aus einem einzigen WSDL-Vertrag zu generieren. Es gibt ein großartiges Projekt auf CodePlex, WCSF.blue, das Ihnen helfen kann, Vertrag-zuerst Service-Entwicklung zu machen.

0

Für Frage 1: die einzige Möglichkeit, die eingehende Nachricht zu überprüfen, ist die Erstellung einer SOAP-Erweiterung, die die eingehende Nachricht anhand des erwarteten Schemas überprüft. Der Grund dafür ist, dass die .NET-Installation das eingehende XML in ein Objekt deserialisiert, bevor es in Ihre Webmethode eintritt. Wenn ein Problem mit dem eingehenden XML-Code auftritt, wird Ihre Webmethode nicht eingegeben und ein SOAP-Fehler wird an den Client zurückgegeben.Ein anderes Problem ist, dass der Deserializer möglicherweise nicht "richtig" deserialisiert. Lesen Sie die XML Schema Validation article für weitere Informationen.

In Bezug auf Frage 2: Ihr Ansatz ist richtig für die erste Entwicklung des Vertrags mit (asmx) Web-Services. Meine Frage ist, warum Sie WCF nicht verwenden, um einen Webdienst anstelle der älteren ASMX-Technologie bereitzustellen. WCF supports schema validation as well.

Verwandte Themen