从 ASMX Web 服务读取 XML 数据以实现 Jquery 自动完成

发布于 2024-11-01 10:59:46 字数 2699 浏览 2 评论 0原文

我和 ASMX Web 服务无法连接。我们争论。她提起了我们过去的争论。很痛苦。我们的关系触礁了!

我有一个 ASMX Web 服务,但尚未使用 Newtonsoft 库对其进行序列化(此处解释了原因:http://encosia.com/2011/04/13/asp-net-web-services-mistake-manual-json-serialization/ )。它看起来像这样:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string[] GetCitiesWithState(string isoalpha2, string prefixText)
    {
        var dict = AtomicCore.CityObject.GetCitiesInCountryWithStateAutocomplete(isoalpha2, prefixText);
        string[] cities = dict.Values.ToArray();
        return cities;
    }

足够简单吧?它在搜索 new 时返回此内容:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <string>New Orleans, Louisiana</string>
  <string>New York, New York</string>
</ArrayOfString>

我期待 JSON,但经过一番阅读后,似乎我不应该尝试序列化输出 - 它应该会发生,对吗?无论如何,我在前端有以下 JQuery:

$('#<%=txtCity.ClientID%>').autocomplete('<%=ResolveUrl("~/AtomicService/Assets.asmx/GetCitiesWithState")%>', {
            dataType: 'json',
            httpMethod: 'POST',
            contentType: 'application/json; charset=utf-8',
            parse: function (data) {
                var rows = new Array();
                for (var i = 0; i < data.d.length; i++) {
                    rows[i] = { data: data.d[i], value: data.d[i].Value, result: data.d[i].Value };
                }
                return rows;
            },
            formatItem: function (row, i, n) {
                return row.Value;
            },
            extraParams: {
                minChars: 2,
                isoalpha2: '<%=Session["BusinessCountry"].ToString()%>',
                maxRows: 20,
                prefixText: function () {
                    return $('#<%=txtCity.ClientID%>').val()
                }
            },
            max: 20
        }).result(function (event, data, formatted) {
            if (data) {
                alert(data['Key']);
            }
        });

我可以使用 Chrome 看到调用:

what one can see in Chrome

然而事情还是发生了!没有 Jquery 错误,没有烟花,什么都没有。她不理我。

起初我责怪 web 服务,但我认为这可能与我在 jquery 中解析和格式化数据的方式有更多关系。

所以,我的问题是,我做错了什么以及如何使自动完成功能正常工作?

感谢帮助:)

编辑:这可能没有帮助,但这就是我在 Fiddler 中看到的:

在此处输入图像描述

Me and ASMX web services do not get on. We argue. She brings up arguments we had in the past. It's a pain. Our relationship is on the rocks!

I have an ASMX web service, which I haven't serialised with the Newtonsoft library (as explained why here: http://encosia.com/2011/04/13/asp-net-web-services-mistake-manual-json-serialization/). It looks like this:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string[] GetCitiesWithState(string isoalpha2, string prefixText)
    {
        var dict = AtomicCore.CityObject.GetCitiesInCountryWithStateAutocomplete(isoalpha2, prefixText);
        string[] cities = dict.Values.ToArray();
        return cities;
    }

Simple enough right? It return this when searching for new:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <string>New Orleans, Louisiana</string>
  <string>New York, New York</string>
</ArrayOfString>

I was expecting JSON, but after a bit of reading, it seems I shouldn't try and serialise the output - it should just happen right? Anyway, so I have the following JQuery on the frontend:

$('#<%=txtCity.ClientID%>').autocomplete('<%=ResolveUrl("~/AtomicService/Assets.asmx/GetCitiesWithState")%>', {
            dataType: 'json',
            httpMethod: 'POST',
            contentType: 'application/json; charset=utf-8',
            parse: function (data) {
                var rows = new Array();
                for (var i = 0; i < data.d.length; i++) {
                    rows[i] = { data: data.d[i], value: data.d[i].Value, result: data.d[i].Value };
                }
                return rows;
            },
            formatItem: function (row, i, n) {
                return row.Value;
            },
            extraParams: {
                minChars: 2,
                isoalpha2: '<%=Session["BusinessCountry"].ToString()%>',
                maxRows: 20,
                prefixText: function () {
                    return $('#<%=txtCity.ClientID%>').val()
                }
            },
            max: 20
        }).result(function (event, data, formatted) {
            if (data) {
                alert(data['Key']);
            }
        });

I can see the calls using Chrome:

what one can see in Chrome

And yet stuff all happens! There is no Jquery errors, no fireworks, no anything. She is ignoring me.

At first I was blaming the webservice, but I think this may have more to do with how I'm parsing and formatting the data in jquery.

So, my question is, what am I doing wrong and how can I make the autocomplete work correctly?

Help appreciated :)

EDIT: It may not be helpful, but this is what I see in Fiddler:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

开始看清了 2024-11-08 10:59:46

jQuery UI 自动完成不再使用 formatItem 方法。该方法和许多其他此类方法存在于自动完成的早期版本中,该版本是一个插件此处

我已经使用 jQuery UI 的自动完成功能重写了您的代码,它适用于以下 htm 和 asmx 文件。

请参阅 jQueryUI 自动完成 上的演示,了解更多可以使用的方法。

我使用了 www.json.org 中的 json2.min.js
此外,我还向 Service1 类添加了 [System.Web.Script.Services.ScriptService] 属性,以便可以直接从 jQuery 作为 json Web 服务调用它。

这些文章对我有帮助:

ASMX 和 JSON – 常见错误和误解

使用jQuery 使用 ASP.NET JSON Web 服务

在 ASP.NET AJAX 中使用 jQuery 时要避免的 3 个错误

htm 文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>jQuery to ASMX</title>
    <link rel="Stylesheet" type="text/css"
          href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/cupertino/jquery-ui.css"/>

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>

    <script type="text/javascript"
            src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script>

    <script type="text/javascript" src="http://localhost/Scripts/json2.min.js"></script>
</head>
<body>

<script type="text/javascript">
    $(document).ready(function() {

        $("#txtInput").autocomplete({
            source:function (request, response) {
                var paramters = {
                    isoalpha2: '<%=Session["BusinessCountry"].ToString()%>',
                    prefixText: request.term
                };
                $.ajax({
                    url: 'Service1.asmx/GetCitiesWithState',
                    type: 'POST',
                    dataType: 'json',
                    contentType: 'application/json; charset=utf-8',
                    data: JSON.stringify(paramters),
                    success: function(data) {
                        response($.each(data.d, function(index, value) {
                            return {
                                label: value,
                                value: index
                            }
                        }));
                    }
                });
            },
            minLength:2,
            delay:500
        });

    });
</script>

<p>
    Hello, World!</p>
<label for="txtInput">
    Enter the string here:</label><input type="text" id="txtInput"/>
</body>
</html>

asmx 文件

using System.Web.Script.Services;
using System.Web.Services;

namespace jQueryAutoCompleteBackEnd
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService]
    public class Service1 : WebService
    {

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string[] GetCitiesWithState(string isoalpha2, string prefixText)
        {
            return new string[] { "New Orleans, Lousiana", "New York, New York" };
        }

    }
}

The jQuery UI autocomplete does not anymore use the formatItem method. That and many other such methods were present in autocomplete's earlier version that was a plugin here

I have rewritten your code using the jQuery UI's autocomplete and it works for me with the below htm and asmx files.

Refer to the demos on the jQueryUI autocomplete for more methods you could use.

I have used the json2.min.js from www.json.org
Also I have added the [System.Web.Script.Services.ScriptService] attribute to the Service1 class so that it could directly be invoked from jQuery as a json web service.

These articles helped me:

ASMX and JSON – Common mistakes and misconceptions

Using jQuery to Consume ASP.NET JSON Web Services

3 mistakes to avoid when using jQuery with ASP.NET AJAX

The htm file

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>jQuery to ASMX</title>
    <link rel="Stylesheet" type="text/css"
          href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/cupertino/jquery-ui.css"/>

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>

    <script type="text/javascript"
            src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script>

    <script type="text/javascript" src="http://localhost/Scripts/json2.min.js"></script>
</head>
<body>

<script type="text/javascript">
    $(document).ready(function() {

        $("#txtInput").autocomplete({
            source:function (request, response) {
                var paramters = {
                    isoalpha2: '<%=Session["BusinessCountry"].ToString()%>',
                    prefixText: request.term
                };
                $.ajax({
                    url: 'Service1.asmx/GetCitiesWithState',
                    type: 'POST',
                    dataType: 'json',
                    contentType: 'application/json; charset=utf-8',
                    data: JSON.stringify(paramters),
                    success: function(data) {
                        response($.each(data.d, function(index, value) {
                            return {
                                label: value,
                                value: index
                            }
                        }));
                    }
                });
            },
            minLength:2,
            delay:500
        });

    });
</script>

<p>
    Hello, World!</p>
<label for="txtInput">
    Enter the string here:</label><input type="text" id="txtInput"/>
</body>
</html>

The asmx file

using System.Web.Script.Services;
using System.Web.Services;

namespace jQueryAutoCompleteBackEnd
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService]
    public class Service1 : WebService
    {

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string[] GetCitiesWithState(string isoalpha2, string prefixText)
        {
            return new string[] { "New Orleans, Lousiana", "New York, New York" };
        }

    }
}
将军与妓 2024-11-08 10:59:46

asmx webmethod 返回 XML 而不是 JSON 的原因是因为 HTTP 方法是 GET 而不是 POST

为了让自动完成插件使用 POST,您必须使用回调函数来实现源参数,看这里

The reason that the asmx webmethod is returning XML rather than JSON is because the HTTP method is GET rather than POST.

In order for the autocomplete plugin to use POST you'll have to implement the source parameter using a callback function, see here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文