Вызов WebMethods с помощью XmlHttpRequest и чистого JavaScript

У меня есть то, что должно быть относительно простой задачей, которая, честно говоря, поставила меня в тупик. Я исследовал это до тех пор, пока мой мозг не сгорел, и теперь я катаюсь на лодке и прошу вас, ребята, о помощи.

Вот сценарий:

  • У меня есть страница ASPX (Q2.aspx), украшенная атрибутами WebService, WebServiceBinding и ScriptService.
  • Эта страница содержит метод GetAllContacts, украшенный атрибутом WebMethod и возвращающий строку, содержащую данные JSON. (Что бы это ни стоило, сама страница не содержит других элементов управления или функций.)
  • У меня есть HTML-страница, содержащая JavaScript, который использует объект XmlHttpRequest для вызова GetAllContacts WebMethod на странице ASPX и преобразования данных JSON в таблицу HTML.
  • Я проверил, что мой файл Web.Config содержит соответствующие обработчики протоколов для HttpGet и HttpPut в разделе WebServices под System.Web.webServices.
  • Я проверил, что мой файл Web.Config содержит запись ScriptModule в разделе System.webServer.modules и соответствует соответствующей документации.

Однако, когда я просматриваю HTML-страницу в браузере, происходит следующее:

  • Веб-запрос проходит, но результаты относятся к необработанному HTML со страницы ASPX.
  • Метод GetAllContacts никогда не вызывается, о чем свидетельствует установка точки останова в его коде.
  • Однако код для вызова веб-службы вызывается, и функция обратного вызова JavaScript, которая вызывается после завершения запроса, вызывается должным образом.

Похоже, что код JavaScript в значительной степени настроен правильно, но по какой-то причине, которая полностью ускользает от меня на данный момент, HTML-страница просто не будет выполнять WebMethod на странице ASPX, а просто возвращает страницу, как если бы это был простой HTML-запрос GET. Ясно, что HTML-документ не может быть оценен функцией JavaScript eval, что подводит меня к моей проблеме. (Также обратите внимание, что данные JSON нигде не появляются в возвращаемом HTML.)

Я, честно говоря, сбит с толку. Я просмотрел десятки статей Microsoft, статьи StackOverflow, статьи CodeProject и черт знает что еще. Мой код выглядит нормально. Но я знаю лучше. Мне не хватает чего-то простого, глупого и очевидного. Мне просто нужно, чтобы кто-то указал мне на это.

Ниже вы найдете код страницы ASPX и код HTML в надежде, что они прольют свет.

Код ASPX

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Q2.aspx.cs" Inherits="Satuit.Q2" enablesessionstate="False" %>
<html>
    <body>
        <form runat="server" id="frmMain"/>
    </body>
</html>
-- Codebehind
using System.IO;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

namespace Satuit
{
    [WebService(Namespace="http://tempuri.org")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
    [ScriptService]
    public partial class Q2 : Page
    {

        [WebMethod]
        public static string GetAllContacts()
        {
            return LoadJsonData();
        }

        private static string LoadJsonData()
        {
            using (var stringWriter = new StringWriter())
            {

                string xmlUri = HttpContext.Current.Server.MapPath("\\XmlData\\Contacts.xml");
                string xslUri = HttpContext.Current.Server.MapPath("\\XmlData\\Q2.xsl");

                using (var xmlTextReader = new XmlTextReader(xmlUri))
                {
                    var xpathDocument = new XPathDocument(xmlTextReader);
                    var xslTransform = new XslCompiledTransform();

                    xslTransform.Load(xslUri);
                    xslTransform.Transform(xpathDocument, null, stringWriter);

                    return stringWriter.ToString();
                }
            }
        }
    }
}

HTML-код

    var objectData; // Receives the objectified results of the JSON request.

    var xmlhttp;
    if(window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }

    xmlhttp.open("GET", "/Q2.aspx/GetAllContacts", true);
    xmlhttp.setRequestHeader("content-type", "application/x-www-form-urlencoded");
    xmlhttp.onreadystatechange = function () 
    {
        if (xmlhttp.readyState == 4) 
        {
            if (xmlhttp.status == 200)
            {
                var jsonResultBuffer = xmlhttp.responseText;
                objectData = eval(jsonResultBuffer);
                DisplayTable();
            }
        }
    };
    xmlhttp.send(null);

    function DisplayTable()
    {       
        var sHtml = "";     
        sHtml = "<table><tr><th>ID</th><th>First</th><th>Last</th><th>Address</th></tr>";           
        for(i = 0; i < objectData.length; i++)
        {
            sHtml += "<tr>";
            sHtml += "<td>" + objectData.ID;
            sHtml += "<td>" + objectData.firstName + "</td>";
            sHtml += "<td>" + objectData.lastName + "</td>";
            sHtml += "<td>" + objectData.address + "</td>"; 
            sHtml += "</tr>"
        }
        sHtml += "</table>"         
        document.getElementById("divTable").innerHTML = sHtml;
    }    
</script>

Сведения о среде разработки

  • Перспектива Ultimate SP 2
  • Визуальная студия 2008
  • .NET Framework 3.5
  • Решение еще не развернуто, поэтому оно работает на «локальном веб-сервере», предоставляемом Visual Studio. (Заставляет меня задуматься, не следует ли мне просто развернуть IIS под Vista.)
  • Обратите внимание, что страница ASPX, содержащая WebMethod, и страница HTML находятся в одном и том же решении.

person Mike Hofer    schedule 22.06.2010    source источник
comment
Я не уверен, но думаю, что веб-службу asp.net нужно вызывать с помощью SOAP.   -  person Fopfong    schedule 22.06.2010
comment
Нет, Фопфонг, это не так.   -  person TheGeekYouNeed    schedule 22.06.2010
comment
Майк, где ты размещаешь свой веб-сервис? Он установлен в виртуальном каталоге или как приложение на сервере? Если страница не обрабатывается, обработка ASP.Net не выполняется. Убедитесь, что ваш IIS настроен правильно. Я предполагаю, что это папка, в которой живет ваш код.   -  person TheGeekYouNeed    schedule 22.06.2010
comment
@Cen, это решение еще не развернуто и существует только на моей машине разработки. Я добавил информацию об окружающей среде в основной пост выше. Сам WebService находится в том же решении, что и HTML-страница. И спасибо, что посмотрели это. Я рву на себе волосы!   -  person Mike Hofer    schedule 22.06.2010
comment
Вы пытались увидеть, можете ли вы использовать jQuery, чтобы сделать это для вас? (Просто как тест, а не как решение) Более простой реализацией может быть использование AutocompleteExtender из Ajax ToolKit. Просто пытаюсь установить, можем ли мы общаться ЛЮБЫМИ средствами   -  person TheGeekYouNeed    schedule 22.06.2010


Ответы (2)


Пожалуйста, попробуйте следующее, используя jquery, чтобы увидеть, доступен веб-сервис или нет.

$.ajax({
        type: "POST",
        url: "Q2.aspx/GetAllContacts",
        data: "",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(response) {
           alert("success");
        },
        error: function(response, aa) {
            alert("fail");
        }
    });

Турейн

person Thurein    schedule 25.06.2010

Я думаю, нам нужно вызвать веб-метод с запросом POST, попробуйте изменить эту часть кода.

xmlhttp.open("POST", "/Q2.aspx/GetAllContacts", true);
xmlhttp.setRequestHeader("content-type", "application/json");
xmlhttp.setRequestHeader("Accept", "application/json");
xmlhttp.onreadystatechange = function () 
{
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) 
    {
            var jsonResultBuffer = JSON.parse(xmlhttp.responseText);
            objectData = jsonResultBuffer.d;
            DisplayTable();
    }
};

Ответ возвращается в формате JSON с «d» в качестве ключа в xmlhttp.responseText.

person khagesh    schedule 26.06.2012
comment
Спасибо, что показали мне, как установить заголовок для ответа в XMLHttpRequest. - person tom_mai78101; 27.01.2017