2009-05-22 79 views
0

由於某種原因,我的web服務不喜歡我發送的數據。我不斷收到以下錯誤:.Net Webservice不會接受XML調用的參數

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

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

任何想法?

這裏是我的代碼:

$.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

請問你的web服務接受輸入XML的形式?爲什麼你需要設置上面的contentType參數? – shahkalpesh 2009-05-22 23:36:35

+3

這是我的猜測。您正在將contentType設置爲xml,但數據不是xml格式。 – shahkalpesh 2009-05-22 23:41:25

回答

2

data選項將參數作爲查詢字符串(GET)而不是post來傳遞,而content-type需要是application/json。這是完整的語法。

$.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

事情是我想要在XML迴應。我會使用JSON,但我很難找回正確的序列化.Net對象。 – GreenEggs 2009-05-23 02:17:12

+0

只需將參數「dataType」更改爲「xml」即可。請嘗試上面的更新腳本。 – 2009-05-23 02:41:48

1

我建議你嘗試soapUI。用它來發送請求,並觀察響應。查看請求看起來像soapUI發送的內容。然後嘗試發送相同的東西。

0

如果你想通過JSON返回序列化的.Net對象,你需要做一些事情。假設你正在使用jQuery ajax調用,它應該只是工作(在對下面提到的服務進行更改後),因爲jQuery爲你附加了回調參數。如果你不使用jQuery,你只需要自己附加回調參數,指向你希望成功調用的任何js函數。

  • 裝飾你的經營合同設置ResponseFormat.WebMessageForm.Json (如[WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest,ResponseFormat = WebMessageFormat.Json,RequestFormat = WebMessageFormat.Json)]
  • 創建自Stream繼承的類(見下文):

    public class JSONCallbackStream : Stream 
    

    { 專用流_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); 
        } 
    } 
    

    }

  • 創建一個從IHttpModule的繼承的類,並確保你有在web.config中的條目該下的System.Web - >的HttpModules(也system.webServer - 如果>模塊上IIS 7),見下文類:

    public class JSONCallback : IHttpModule 
    

    { 公共無效的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

您的解決方案可以將數據表序列化爲JSON嗎?這是我的主要問題。我嘗試實施其他人的建議,但尚未取得預期的結果。 – GreenEggs 2009-05-26 20:17:21

1

您還沒有實際發送XML數據到你的Web服務。目前,鑑於你的示例代碼片段,您在標準的HTML表單的編碼格式發送:

field1=value1&field2=value2&field3=value3 

你可能需要改變你的數據是XML,沿着線:

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

要後者,則還需要更改Web服務的簽名採取單一字符串,這就是後來反序列化:

[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; 
...... 
} 

這大概也是需要注意的是該屬性你已裝飾你的服務方法:

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

與你的服務方法的返回值有關,而不是輸入數據。通過裝飾,你的RESPONSE將被格式化爲XML。這不會影響您的服務輸入。

希望這會有所幫助。

0

試試這個:

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