2010-12-08 32 views
1

J'ai un service Web SOAP qui était basé sur un schéma XSD (le schéma généré des classes qui a été utilisée comme paramètre d'entrée pour la méthode de service Web), en tant que tel:Valider SOAP par rapport au schéma XSD?

public class CMService : WebService 
{ 
    [WebMethod(Description = "Submit trades")] 
    public bool SubmitTrades(List<TradesTrade> trades) 
    { 
     // Validation, if true, return true, else, return false; 
     return true; 
    } 
} 

Comment puis-je valider était transmis contre le schéma (Dans ce cas, la classe de schéma est TradesTrades)?

Merci.

Répondre

0

Je suis contre les valider manuellement les champs au lieu :)

0

Ce n'est pas facile de le faire et cela peut ne pas valoir la peine. Considérons que si le code XML envoyé à votre service ne correspond pas au schéma, il ne sera pas désérialisé correctement. Si c'est déjà assez grave, votre service ne sera même pas appelé. Cela dit, si vous avez vraiment besoin de faire cela, vous devriez regarder l'exemple d'une classe SoapExtension. Je recommande que vous obteniez d'abord que l'exemple fonctionne exactement tel quel. Ensuite, je vous recommande de créer une nouvelle version de l'exemple et de le faire faire ce que vous voulez. Ce que vous voulez, c'est modifier les méthodes WriteInput et/ou WriteOutput pour valider votre XML en utilisant l'une des méthodes disponibles, peut-être en configurant un XmlReader pour faire la validation et lire depuis le flux d'entrée; et configurer un XmlWrite pour écrire dans le flux de sortie; puis en exécutant une boucle pour lire à partir de l'entrée et écrire sur la sortie.

0

J'ai utilisé XML beans (cadre contraignant xml) dans mon précédent projet. Nous avons créé le schéma xml, puis généré l'objet beans xml à partir du schéma. Ces objets XML beans ont beaucoup de méthodes pratiques pour vérifier la validité du XML et les valeurs transmises dans le cadre du XML.

S'il vous plaît laissez-moi savoir, Si vous avez une question particulière sur les beans XML.

+0

Il parle de .NET. –

+0

Mais cela n'a pas été spécifié. Désolé c'était une erreur. Je dois regarder la classe pour dire son .Net. –

0

J'ai eu le même problème moi-même, la réponse est qu'il est possible de le faire sans avoir besoin de valider manuellement tous les champs (ce qui est sujet à erreur, plus puisque vous avez déjà le schéma vous pouvez aussi l'utiliser).

See this a article on the topic.

Fondamentalement, le processus à suivre est d'abord lire le Request.InputStream original dans un XmlDocument puis appliquez votre schéma et la validation au corps SOAP à l'intérieur.

[WebMethod(Description = "Echo Soap Request")] 
public XmlDocument EchoSoapRequest(int input) 
{ 
    // Initialize soap request XML 
    XmlDocument xmlSoapRequest = new XmlDocument(); 
    XmlDocument xmlSoapRequestBody = new XmlDocument(); 

    // Get raw request body 
    HttpContext httpContext = HttpContext.Current; 
    Stream receiveStream = httpContext.Request.InputStream 

    // Move to begining of input stream and read 
    receiveStream.Position = 0; 
    using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) 
    { 
    // Load into XML document 
    xmlSoapRequest.Load(readStream); 
    } 

    // Now we have the original request, strip out the request body 
    foreach (XmlNode node in xmlSoapRequest.DocumentElement.ChildNodes) 
    { 
    if (node.NodeType == XmlNodeType.Element && node.LocalName == "Body" && node.FirstChild != null) 
    { 
     xmlSoapRequestBody.LoadXml(node.FirstChild.InnerXml); 
    } 
    } 

    // Validate vs Schema 
    xmlSoapRequestBody.Schemas.Add("http://contoso.com", httpContext.Server.MapPath("MySchema.xsd")) 
    xmlSoapRequestBody.Validate(new ValidationHandler(MyValidationMethod)); 
} 
+0

@Steven: J'ai un certain nombre de problèmes avec votre code. Premièrement, que se passe-t-il s'il y a plus d'un enfant de l'élément 'SOAP: Body'? Deuxièmement, que se passe-t-il s'il y a un élément nommé 'Body' mais dans un espace de noms différent? Vous vous trompez pour l'élément SOAP: Body. Aussi, il me semble peu logique de créer 'xmlSoapRequestBody' en ré-analysant le XML interne - vous avez déjà un XmlNode, alors pourquoi ne pas l'utiliser? Pensez en termes de 'XmlReader.Create (nouveau XmlNodeReader (node.FirstChild), nouveau XmlReaderSettings {jeu de paramètres de validation})' –

+0

Alors que vos points sont théoriquement possibles, il semble que vous n'ayez pas utilisé beaucoup de validation Soap ou Schema auparavant.1) Dans Soap, votre méthode est le seul enfant de l'élément , 2) Son savon, l'élément Body contient le message soap, alors qu'il est théoriquement possible d'avoir différents éléments Body dans deux namespaces cela n'arrive pas dans la réalité. 3) Les schémas s'appliquent aux éléments XmlDocument, pas aux XmlNodes. Ce code fonctionne et il fonctionne dans 99,9% des situations, c'est un assez bon nombre pour moi. –

+0

@Steven: très mal à propos de mon expérience SOAP, BTW, et mon premier service ASMX validé à la fois XML entrant et sortant en utilisant un 'SoapExtension'. OBTW, à quoi ressemble un message SOAP quand l'entrée 'message' a plus d'une partie? –