2009-05-22 3 views
0

Pour une raison quelconque, mon service Web n'aime pas les données que je lui envoie. Je continue à obtenir l'erreur suivante:.Service Web ne prend pas de paramètres pour l'appel XML

System.InvalidOperationException: Request format is invalid: text/xml; charset=utf-8. 

à System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() à System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

Toutes les idées?

Voici mon code:

$.ajax({ 
    type: "POST", 
    url: "/wsCheckout.asmx/loginUser", 
    data: "userName=" + userName + "&pw=" + pw, 
    contentType: "text/xml; charset=utf-8", 
    dataType: "xml", 
    cache: false, 
    beforeSend: function(n){ showLoading(); }, 
    complete: function(n){ hideLoading(); }, 
    success: function(r) {   
     if(checkResponse(r) == true){ 
     closeBox(aspxIdPrefix + "login"); 
     hideBox(aspxIdPrefix + "login");   
     openBox("#shippingAddress");  
     }   
    } // end success 
}); //end AJAX 

[WebMethod(EnableSession = true)] 
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Xml)] 
public DataTable loginUser(string userName, string pw) 
{ 
...... 
} 
+0

Est-ce que votre webservice accepter l'entrée sous forme de xml? Pourquoi avez-vous besoin de définir le paramètre contentType ci-dessus? – shahkalpesh

+3

C'est ma conjecture. Vous définissez le contentType sur xml mais les données ne sont pas au format xml. – shahkalpesh

Répondre

2

L'option data transmet les paramètres en tant que querystring (GET) au lieu de post et le type de contenu doit être application/json. Voici la syntaxe complète.

$.ajax({ 
    type: "POST", 
    url: "/wsCheckout.asmx/loginUser", 
    data: "{userName:'" + userName + "',pw:'" + pw+"'}", 
    contentType: "application/json; charset=utf-8", 
    dataType: "xml", 
    cache: false, 
    beforeSend: function(n){ showLoading(); }, 
    complete: function(n){ hideLoading(); }, 
    success: function(r) {   
     if(checkResponse(r) == true){ 
     closeBox(aspxIdPrefix + "login"); 
     hideBox(aspxIdPrefix + "login");   
     openBox("#shippingAddress");  
     }   
    } // end success 
}); 
+0

Chose est que je veux une réponse en XML. J'utiliserais JSON mais j'ai du mal à récupérer les objets .Net sérialisés. – GreenEggs

+0

Remplacez simplement le paramètre "dataType" par "xml". Veuillez essayer le script mis à jour ci-dessus. –

1

Je vous suggère d'essayer soapUI. Utilisez-le pour envoyer une demande et regardez la réponse. Voyez ce que la requête ressemble à ce que soapUI envoie. Ensuite, essayez d'envoyer la même chose.

0

Si vous souhaitez renvoyer des objets .Net sérialisés via JSON, vous devez effectuer certaines opérations. En supposant que vous utilisez les appels ajax jQuery, il devrait juste travailler (après avoir apporté les modifications à votre service mentionné ci-dessous) étant donné que jQuery ajoute le paramètre de rappel pour vous. Si vous n'utilisez pas jQuery, il vous suffit d'ajouter vous-même le paramètre callback, en pointant vers la fonction js que vous souhaitez appeler en cas de succès.

  • Décorez votre mise en contrat d'exploitation du ResponseFormat.WebMessageForm.Json (par exemple [WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest,ResponseFormat = WebMessageFormat.Json,RequestFormat = WebMessageFormat.Json)])
  • créer une classe qui hérite de flux (voir ci-dessous):

    public class JSONCallbackStream : Stream 
    

    { _stream privé Stream ;

    private string _callbackFunction = string.Empty; 
    
    public JSONCallbackStream(Stream stream) 
    { 
        _stream = stream; 
    } 
    
    public override bool CanRead 
    { 
        get { return _stream.CanRead; } 
    } 
    
    public override bool CanSeek 
    { 
        get { return _stream.CanSeek; } 
    } 
    
    public override bool CanWrite 
    { 
        get { return _stream.CanWrite; } 
    } 
    
    public override long Length 
    { 
        get { return _stream.Length; } 
    } 
    
    public override long Position 
    { 
        get { return _stream.Position; } 
        set { _stream.Position = value; } 
    } 
    
    public string CallbackFunction 
    { 
        get { return _callbackFunction; } 
        set { _callbackFunction = value; } 
    } 
    
    public override void Flush() 
    { 
        _stream.Flush(); 
    } 
    
    public override int Read(byte[] buffer, int offset, int count) 
    { 
        return _stream.Read(buffer, offset, count); 
    } 
    
    public override long Seek(long offset, SeekOrigin origin) 
    { 
        return _stream.Seek(offset, origin); 
    } 
    
    public override void SetLength(long value) 
    { 
        _stream.SetLength(value); 
    } 
    
    public override void Write(byte[] buffer, int offset, int count) 
    { 
        if (CallbackFunction != string.Empty) 
        { 
         // This MUST be a one-time write to the underlying stream - any more than 1 write means 
         // that the stream will be truncated/an exception could be thrown 
         string content = CallbackFunction + "(" + Encoding.UTF8.GetString(buffer) + ");"; 
         byte[] contentBytes = Encoding.UTF8.GetBytes(content); 
         _stream.Write(contentBytes, 0, Encoding.UTF8.GetMaxCharCount(contentBytes.Length)); 
        } 
        else 
        { 
         _stream.Write(buffer, offset, count); 
        } 
    } 
    

    }

  • créer une classe qui hérite de IHttpModule et assurez-vous que vous avez des entrées dans web.config pour cette sous system.web -> httpModules (et aussi system.webServer -> modules si sur IIS 7), voir la classe ci-dessous:

    public class JSONCallback : IHttpModule 
    

    { public void Dispose() {}

    //looks for a callback parameter, if found it wraps the return in the callback string 
    public void Init(HttpApplication app) 
    { 
        app.BeginRequest += delegate 
        { 
         HttpContext ctx = HttpContext.Current; 
    
         if ((ctx.Request.RequestType.ToUpper() == "GET")) 
         { 
          string[] parameters = ctx.Request.QueryString.GetValues("callback"); 
    
          if (parameters != null && parameters.Length == 1) 
          { 
           JSONCallbackStream _captureStream = new JSONCallbackStream(ctx.Response.Filter); 
           _captureStream.CallbackFunction = parameters[0]; 
    
           ctx.Response.Filter = _captureStream; 
          } 
         } 
        }; 
    
    } 
    

    }

+0

Votre solution fonctionnera-t-elle sur la sérialisation d'une table de données vers JSON? C'est mon problème principal. J'ai essayé de mettre en œuvre les suggestions des autres, mais je n'ai pas encore obtenu les résultats souhaités. – GreenEggs

+0

Aussi, cela fonctionnera-t-il avec un site .Net 2.0? – GreenEggs

+0

Le code ci-dessus est utilisé dans un service WCF .Net 2.0. En ce qui concerne la sérialisation d'un DataTable, vous devrez probablement jouer un peu avec. Je suppose que la méthode GetXML() du DataSet vous aiderait à atteindre votre objectif. – ScottD

1

Vous n'êtes pas réellement envoyer des données XML à votre service Web.À l'heure actuelle, compte tenu de votre extrait de code exemple, votre envoi dans les formulaires HTML standard format codé:

field1=value1&field2=value2&field3=value3 

Vous avez probablement besoin de changer vos données pour être xml, le long des lignes de:

'<data><userName>' + userName + '</userName><pw>' + pw + '</pw></data>' 

To ne ce dernier, vous devrez également modifier votre signature de service Web pour prendre une seule chaîne, qui est ensuite désérialisée:

[XmlRoot("data")] 
public class UserRequestData 
{ 
    public string userName { get; set; } 
    public string pw { get; set; } 
} 

[WebMethod(EnableSession = true)] 
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Xml)] 
public DataTable loginUser(string xmlUserRequest) 
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(UserRequestData)); 
    StringReader reader = new StringReader(xmlUserRequest); 
    UserRequestData data = serializer.Deserialize(reader); 

    string userNme = data.UserName; 
    string pw = data.Pw; 
...... 
} 

Il est probablement aussi important de noter que l'attribut ont décoré votre méthode de service avec:

[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Xml)] 

Cela a à voir avec la valeur de retour de votre méthode de service, et non avec les données d'entrée. En décorant avec cela, votre réponse sera formatée avec xml. Cela n'affecte pas l'entrée de votre service.

Espérons que cela aide.

+0

Cela aide. Surtout la dernière partie. Merci. – GreenEggs

0

Essayez ceci:

contentType: "text/xml; charset=\"utf-8\"", 
+0

Avez-vous lu la réponse acceptée? –

Questions connexes