.Net Webservice不会接受XML调用的参数

时间:2009-05-22 23:33:24

标签: .net jquery xml ajax web-services

出于某种原因,我的网络服务不喜欢我发送的数据。我一直收到以下错误:

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

at 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)
{
......
}

5 个答案:

答案 0 :(得分:2)

data选项将参数作为查询字符串(GET)而不是post传递,内容类型需要是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
});

答案 1 :(得分:1)

我建议你试试soapUI。用它来发送请求,并观察响应。查看soapUI发送的请求。然后尝试发送相同的东西。

答案 2 :(得分:1)

您实际上并未向您的网络服务发送XML数据。目前,根据您的示例代码段,您使用标准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格式化。这不会影响您的服务输入。

希望这有帮助。

答案 3 :(得分: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的类,并确保在system.web - &gt;下为web.config提供了条目。 httpModules(以及系统.webServer - &gt;模块,如果在IIS 7上),请参阅下面的类:

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

    }

答案 4 :(得分:0)

试试这个:

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