Home

 
 
 
 
 



 
 
 
 

 
 
 

 
 
 
 
 









Blog2theMax
Il blog del team di Code Architects

Fate un Web Service che riceve una stringa e restiuisce una stringa.
Fate si che l'implementazione del web service restituisca System.Environment.NewLine (la sequenza /r/n).
Fate quindi un chamante del web service e fate si che il chiamante passi anch'esso System.Environment.NewLine.
Lanciate in debug e vedete cosa succede : da entrambi i lati riceventi la sequenza /r/n viene trasformata in /n .. come mai ?

Il fatto è che c'è una specifica dell'XML che dice che una tale sequenza deve essere trasformata (normalizzata) in /n (specificatamente , la sequenza di caratteri asci 13 , 10 deve essere trasformata in 10.
Il responsabile della sparizione del /r è il lato ricevente: di default i web services usano un xmltextreader con la proprietà Normalization impostata a true (provate a serializzare e quindi deserializzare in maniera esplcita un oggetto avente una proprietà stringa impostata con un /r/n usando l'XMLSerializer a cui passate un xmltextreader con la proprietà Normalization impostato prima a true e poi false).
La sparizione della sequenza /r/n puo' essere un bel problema per molte applicazioni.

Per fortuna esiste una soluzione : Per evitare che venga persa la sequenza nella risposta del Web Service occorre intervenire sul proxy lato client andando in override del metodo GetReaderForMessage nel modo seguente:

protected override System.Xml.XmlReader GetReaderForMessage(
 System.Web.Services.Protocols.SoapClientMessage message, int bufferSize) {
 System.Xml.XmlReader l_tmp = base.GetReaderForMessage(message, bufferSize);
  ((System.Xml.XmlTextReader)l_tmp).Normalization = false;
  return l_tmp;
}

(ovviamente non fatelo sul proxy generato dinamicamente , derivate da quello)
Lato server la cosa è piu' articolata : Create una classe custom che deriva da SoapServerProtocolFactory. Tale classe deve restituire un'altra vostra classe custom che deriva da SoapServerProtocol public class MyWSFactory :

System.Web.Services.Protocols.SoapServerProtocolFactory {
 protected override System.Web.Services.Protocols.ServerProtocol CreateIfRequestCompatible(
   System.Web.HttpRequest request) {
  if (request.PathInfo.Length > 0) {
   return null;
  }
  if (request.HttpMethod != "POST") { // need reflection to create the internal UnsupportedRequestProtocol class
   Type l_t = Type.GetType
    ("System.Web.Services.Protocols.UnsupportedRequestProtocol, System.Web.Services, Version=2.0.0.0, Culture=neutral, 
    PublicKeyToken=b03f5f7f11d50a3a"
, true);
   Object l_tmp = l_t.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.CreateInstance, null, null, new object[] { 0x195 });
   return (System.Web.Services.Protocols.ServerProtocol)l_tmp ;
   // return new UnsupportedRequestProtocol(0x195);
   }
   return new MyWS();
  } 
   

Ed ecco l'implementazione della SoapServerProtocol custom  in cui si puo' ottenere una referenza all'XMLTextReader utilizzato :

public class MyWS : System.Web.Services.Protocols.SoapServerProtocol {
 protected override System.Xml.XmlReader GetReaderForMessage(
  System.Web.Services.Protocols.SoapServerMessage message, int bufferSize) {
  System.Xml.XmlReader l_tmp = base.GetReaderForMessage(message, bufferSize);
  ((System.Xml.XmlTextReader)l_tmp).Normalization = false;
  return l_tmp;
 }
}

Come ultimo passo dovete aggiungere nel web .config l'entrata seguente per dire ad ASP.NET di agganciare il vostro soapServerProtocolFactory ...

<configuration>
                <system.web>
                               <webServices>
                                               <soapServerProtocolFactory type ="WSFactory.MyWSFactory, WSFactory" />

 

Poteva essere + facile .. ma per adesso le cose stanno cosi' :)


 
Feed di Blog2theMax
RSS 2.0 | Atom 0.2
Cerca nel blog
Archivio
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Categorie

Powered by: newtelligence dasBlog 1.7.5016.2

 ©2004-2005 Code Architects S.r.l. - All rights reserved  Sign In