【问题标题】:Calling asmx web service from JavaScript yields 404从 JavaScript 调用 asmx Web 服务会产生 404
【发布时间】:2014-03-31 23:37:53
【问题描述】:

我编写了一个 Web 服务,我想从 JavaScript 调用它。问题是我收到 404 错误,并且不确定我做错了什么。

关于如何完成任务的文章很多。我用的是here

这是背后的代码,是的,我确实阅读了评论并添加了 [ScriptService]:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Services;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using BvCommonControls;

namespace MyProject.MyWebService
{
    [WebService(Namespace = "http://microsoft.com/webservices/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService]
    public class svcSignin : WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public String GetStockName(String argEncrypted)
        {
            return js.Serialize("HelloWorld!");
        }
    }
}

JavaScript 代码是:

// Create the URL.
var serviceUrl = "http://mywebsiteaddress.whatever/Folder/myservice.asmx";
var serviceOperation = "/GetStockName";
var serviceData = "myencodedargs";

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: serviceUrl + serviceOperation,
    data: JSON.stringify(serviceData),
    dataType: "json",
    async: true,
    success: ajaxSigninSuccess,
    error: ajaxSigninError
});

function ajaxSuccess(response)
{
    alert(response.d);
}

function ajaxError(response)
{
    alert(response.status + " " + response.statusText);
}

readyState 为 4,状态为 404(未找到页面)。

如果我使用复制和粘贴将url 输入网络浏览器,我会得到带有注释的标准页面:

The following operations are supported. For a formal definition, please review the Service Description.

* GetStockName

问题似乎与类或方法声明之一有关。

更新(网络服务)

根据MSDN,这里是WebServices 部分的所在。

<configuration>
 <system.web>
    <webServices>
      <conformanceWarnings>
        <remove name='BasicProfile1_1'/>
      </conformanceWarnings>
    </webServices>
  </system.web>
</configuration>

这篇CodeProject 文章展示了 System.Web.Handlers.ScriptModule 的去向。

<configuration>
  <system.web>
    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, 
    System.Web.Extensions, Version=3.5.0.0, Culture=neutral, 
    PublicKeyToken=31BF3856AD364E35"/>
    </httpModules>
  </system.web>
</configuration>

更新 2(请求的 RESTful 更新)

我更新了 JavaScript 代码中的 Ajax 部分以符合请求的格式。基本上,如果我在浏览器中访问该页面并单击 GetStockName 链接,那么我会进入一个显示各种 SOAP 格式并在底部显示 HTTP POST 格式的页面。

HTTP POST

The following is a sample HTTP POST request and response. The placeholders shown need to be replaced with actual values.

POST /Folder/myservice.asmx/GetStockName HTTP/1.1
Host: www.mywebsiteaddress.whatever
Content-Type: application/x-www-form-urlencoded
Content-Length: length

argEncrypted=string

我必须对 URL 进行硬编码,如图所示。简单地放置一个像“$.ajax(serviceUrl{”这样的变量是行不通的,有趣的是,添加“url: serviceUrl”作为ajax属性之一也行不通。只有“$.ajax(''{”的构造工作。

$.ajax('http://mywebsiteaddress.whatever/Folder/myservice.asmx/GetStockName'{
    type: 'POST',
    contentType: 'application/json',
    headers: { 'Access-Control-Allow-Origin': '*' },
    crossDomain: true,
    data: '{argEncrypted: "' + serviceData + '"}',
    dataType: "json",
    async: true,
    success: ajaxSuccess,
    error: ajaxError
});

更新 3 (CORS)

问题肯定是跨域或跨域资源共享或CORS之一。旧代码使用jsonp,效果很好,但不支持ASMX页面。

正如我在评论中提到的,问题的一部分也是 Visual Studio。在调试模式下运行 IE11 的 VS2013 不允许 CORS 操作。我必须在 Visual Studio 之外启动 IE11 才能使事情与其他更改一起工作。

以下是我看到的一些链接:link 1link 2,更重要的是link 3

web.config 中的添加/更改调用:

<configuration>
 <system.webServer>
  <httpProtocol>
   <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
   </customHeaders>
  </httpProtocol>
 </system.webServer>
<configuration>

$.ajax 更改包括添加:

type: 'POST',
contentType: 'application/json',
headers: { 'Access-Control-Allow-Origin': '*' },
crossDomain: true,

注意部分

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

根据链接和SO chat 中的讨论,将标头添加到服务中,表明该调用符合 HTTP 1.1。此标头等效于 PHP 标头。

使用 IE11 在 Win7-64 上完成测试。 IE11 支持 CORS,如一个链接中所述。

(已更新问题以反映答案。)

【问题讨论】:

标签: c# javascript asp.net web-services rest


【解决方案1】:

我让代码工作了!

我不确定代码何时开始工作,因为我不是一直通过 IE11 进行测试,而是通过在调试模式下通过 VS2013 运行的启用 JavaScript 的页面与 CORS 页面对话。显然,Visual Studio 禁用了对 ASMX 页面的 CORS 操作。必须脱离 VS 调试器模式。

可能还需要所有其他更改。

【讨论】:

  • 是否有可能,如果可以,如何在 VS 调试环境中对 asmx 页面执行 CORS 操作,基本上是通过 Visual Studio 2013 启动的 IE11 页面?
【解决方案2】:

尝试以下方法:

将以下内容添加到您的 web.config

<webServices>
 <protocols>
  <add name="HttpPost"/>
 </protocols>
</webServices>

另外,在您的 AJAX 请求中,更改此行

data: JSON.stringify(serviceData)

data: '{argEncrypted: "' + serviceData + '"}'

还要确保您有以下 web.config 条目:

<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

【讨论】:

  • 如果它已经存在于 machine.config 中,他不需要 web.config 中的那个条目。
  • 有关 WebServices 的放置信息,请参见更新 2。我很好奇它去了哪里,并研究了这个话题。
  • 问题是跨域问题之一。在更改 $.ajax JavaScript 部分以使其更符合请求的格式时,请参阅上面的更新 2,我得到 response.statusText 以指示实际错误,即它找不到 URL。
猜你喜欢
  • 2014-02-12
  • 2013-03-27
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 2012-02-07
  • 1970-01-01
相关资源
最近更新 更多