2009-09-22 6 views
1

J'utilise C# pour lire des données à partir d'un service Web Java.Modifier la culture lors de la désérialisation du service WCF

J'ai créé une référence de service dans VS2008 sur le serveur, et je peux appeler la méthode qui existe. Cependant, quelques-uns des champs retournés sont de type décimal, et que le proxy WCF généré automatiquement obtient XML arrière, il échoue avec une CommunicationException disant:

"Error in deserializing body of reply message for operation 'getOpenReceivables'." 
"There is an error in XML document (1, 941)." 
"Input string was not in a correct format." 

[Modifier] Voici une stacktrace complète:

at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) 
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) 
at System.Decimal.Parse(String s, NumberStyles style, IFormatProvider provider) 
at System.Xml.XmlConvert.ToDecimal(String s) 
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExecutePortType.Read2_XXNG_OPEN_RECEIVABLES(Boolean isNullable, Boolean checkType) 
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExecutePortType.Read3_Item() 
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer.Deserialize(XmlSerializationReader reader) 
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) 

Je peux voir que le nombre décimal retourné est formaté avec une ponctuation comme décimal. À des fins de test j'ai essayé un Decimal.Parse ("123.99") et ai eu la même erreur. En réglant un

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); 

avant mon code de test pour Decimal.Parse ("123.99") Je commence à travailler. Toutefois, la définition de CurrentCulture avant d'appeler la méthode WCFService ne fait aucune différence.

Y a-t-il des moyens pour que mon objet proxy WCFService puisse comprendre que le XML renvoyé se trouve dans un autre format de culture?

Répondre

2

Avez-vous essayé d'utiliser une implémentation personnalisée IClientMessageFormatter.DeserializeReply()? Le WCF est rempli de points d'extensibilité, il est donc souvent difficile de savoir lequel choisir, mais DeserializeReply semble être le bon outil pour ce travail. Jetez un oeil à this blog post-- sorry its original site is offline so pointing to Internet Archive version qui ressemble à une chose similaire à ce que vous essayez de faire: en utilisant un client WCF pour appeler un service Web non-WCF, et de faire un traitement spécialisé de la réponse pour tenir compte de non-WCF Comportement de type WCF sur le serveur.

Voici un extrait de code de ce blog:

public object DeserializeReply(Message message, object[] parameters) 
{ 
    object helperInstance = Activator.CreateInstance(_return); 

    //we have special condition where service sets Http response code to 403 that signals that an error has occured 
    KeyValuePair<string,object> serviceErrorProperty = message.Properties.FirstOrDefault(p => p.Key == ResponseErrorKey); 
    if (serviceErrorProperty.Key != null) 
    { 
     //we have an error message 
     IResponseErrorProvider responseErrorProvider = helperInstance as IResponseErrorProvider; 
     if (responseErrorProvider != null) 
     { 
      //unpack the error payload from message and assign to the object 
      ResponseError payload = message.GetBody<ResponseError>(); 
      responseErrorProvider.ServiceError = payload; 

      //return fixed null type with error attached to it 
      return helperInstance; 
     } 
    } 

    //another message we might get is <nil-classes type="array"/> for empty arrays. 
    XmlDictionaryReader xdr = message.GetReaderAtBodyContents(); 
    xdr.MoveToContent(); 

    if (xdr.Name == NullMessage) 
    { 
     return helperInstance; //standin for the null value 
    } 

    return _formatter.DeserializeReply(message, parameters); 
} 

public Message SerializeRequest(MessageVersion messageVersion, object[] parameters) 
{ 
    return _formatter.SerializeRequest(messageVersion, parameters); 
} 
+0

En fait, je suis le problème corrigé en éditant le fichier xsd m'a été donnée par le gars qui a fait le webservice. (Vous avez un fichier .wsdl et deux .xsd). Vous avez eu des points puisque cela semble être une bonne solution et un bon lien, mais je ne l'ai pas vraiment essayé. –

+0

Vous devriez avoir au moins collé le code le plus pertinent de l'article de blog - le lien est mort –

+0

désolé @CamiloTerevinto - il était il y a près de 7 ans quand j'ai écrit ceci, bien avant le "doit coller le code avec les liens" la pratique a été formalisée. J'ai trouvé le blog sur Internet Archive et mis à jour ma réponse avec le lien d'archive plus un extrait d'échantillon de code. –

0

Je serais très surpris si la culture est vraiment le problème. La spécification XML indique que les nombres décimaux utilisent le point comme séparateur, et le (de) sérialiseur le sait. Pouvez-vous retracer le message et voir ce qu'il y a dans la position 941? (En passant: j'aime SoapUI pour de telles choses, en plus de traçage WCF) Quand il s'agit de décimales, peut-être la précision différente pourrait être un problème: peut-être que le service Java met plus de 666666666666 avant le 7 final. net decimal peut gérer?

0

Et il y a une deuxième option: la décimale n'est pas vraiment une décimale (encore une fois: le traçage du message serait très éclairant). J'ai trouvé this link qui se plaint un peu des services d'amazon, qui pourraient mettre l'unité dans la valeur décimale (d'ailleurs: WTF!?). Cependant, il y a une description intéressante sur la façon d'interagir avec le message brut avant de le passer à la désérialisation en utilisant l'interface IClientMessageInspector. Si un tel cas étrange est votre problème, vous pouvez soit forcer le fournisseur de services à respecter son propre contrat ou faire un tel tour (si le fournisseur est en dehors de votre sphère de contrôle et dit "c'est par conception").

Questions connexes