简体   繁体   English

从JavaScript调用asmx Web服务会产生404

[英]Calling asmx web service from JavaScript yields 404

I wrote a web service, which I would like to call from JavaScript. 我写了一个Web服务,我想从JavaScript调用它。 The problem is that I receive a 404 error, and not sure what I did wrong. 问题是我收到404错误,并且不确定我做错了什么。

There are many articles on how to achieve the task. 关于如何完成任务的文章很多。 The one that I used is here . 我使用的一个是在这里

Here is the code behind and yes, I did read the comment and did add the [ScriptService]: 这是背后的代码,是的,我确实阅读了注释并添加了[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!");
        }
    }
}

The JavaScript code is: 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 is 4 with status is 404 (page not found). readyState是4,状态是404(找不到页面)。

If I enter the url into a web browser using a copy and paste, I get the standard page with the comment: 如果使用复制和粘贴将URL输入到Web浏览器中,则会得到带有注释的标准页面:

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

* GetStockName

The problem seems to be something with one of the class or method declarations. 问题似乎出在类或方法声明之一上。

UPDATE (Web Services) 更新(Web服务)

According to MSDN , here is where the WebServices section goes. 根据MSDN ,这是WebServices部分的去向。

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

This CodeProject article shows where the System.Web.Handlers.ScriptModule goes. 这篇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>

UPDATE 2 (Requested RESTful update) UPDATE 2(请求的RESTful更新)

I updated the Ajax section in my JavaScript code to conform to the requested format. 我在JavaScript代码中更新了Ajax部分,以符合请求的格式。 Basically, if I go to that page in a browser and click on the GetStockName link, then I get to a page that shows various SOAP formats and at the bottom an HTTP POST format. 基本上,如果我在浏览器中转到该页面并单击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

I had to hard code the URL as shown. 如图所示,我必须对URL进行硬编码。 Simply placing a variable like "$.ajax(serviceUrl{" did not work and interestingly enough adding "url: serviceUrl," as one of the ajax attributes also did not work. Only the construct of "$.ajax(''{" worked. 简单地放置一个像“ $ .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
});

UPDATE 3 (CORS) 更新3(CORS)

The problem is definitely one of cross domain or cross-origin resource sharing or CORS. 问题肯定是跨域或跨域资源共享或CORS之一。 The old code used jsonp, which works nicely, but does not support ASMX pages. 旧代码使用jsonp,效果很好,但不支持ASMX页面。

As mentioned in my comment part of the problem was Visual Studio too. 正如我的评论中提到的,部分问题也是Visual Studio。 VS2013 running IE11 in debug mode does not allow CORS operations. 在调试模式下运行IE11的VS2013不允许进行CORS操作。 I had to launch IE11 outside of Visual Studio to get things to work along with the other changes. 我必须在Visual Studio外部启动IE11才能使事情与其他更改一起使用。

Here are some links that I saw: link 1 , link 2 , and more importantly link 3 . 这是我看到的一些链接: 链接1链接2 ,更重要的是链接3

Additions/changes call for in web.config: 在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>

and the $.ajax changes include adding: $ .ajax的更改包括添加:

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

Note the section 注意部分

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

adds the header to the service that indicates that the call is HTTP 1.1 compliant, per links and the discussion in SO chat . 根据链接和SO chat中的讨论,将标头添加到服务中以指示该呼叫符合HTTP 1.1的标头。 This header is equivalent to the PHP header. 此标头等效于PHP标头。

Testing done on Win7-64 using IE11. 使用IE11在Win7-64上完成测试。 IE11 supports CORS, as noted in one link. 如一个链接所述,IE11支持CORS。

(Question updated to reflect answer.) (问题已更新以反映答案。)

I got the code to work! 我有代码可以工作!

I am not sure when the code started to work, as I was not testing all the time through IE11, but rather through a JavaScript enabled page running through VS2013 in debug mode talking to a CORS page. 我不确定代码何时开始工作,因为我不是一直通过IE11进行测试,而是通过启用了JavaScript的页面通过VS2013以调试模式与CORS页面进行通信来进行测试。 Evidently, Visual Studio disables CORS operations to ASMX pages. 显然,Visual Studio禁用了对ASMX页面的CORS操作。 One has to go outside of VS debugger mode. 一个必须超越VS调试器模式。

All the other changes are probably required as well. 所有其他更改可能也是必需的。

Try the following: 请尝试以下操作:

add the following to your web.config 将以下内容添加到您的web.config中

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

Also, in your AJAX request, change this line 另外,在您的AJAX请求中,更改此行

data: JSON.stringify(serviceData)

to

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

Also ensure you have the following web.config entry: 还要确保您具有以下web.config条目:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM