I wrote a web service, which I would like to call from JavaScript. The problem is that I receive a 404 error, and not sure what I did wrong.
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]:
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:
// 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).
If I enter the url into a web browser using a copy and paste, I get the standard page with the comment:
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)
According to MSDN, here is where the WebServices section goes.
<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.
<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)
I updated the Ajax section in my JavaScript code to conform to the requested format. 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.
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. 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('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)
The problem is definitely one of cross domain or cross-origin resource sharing or CORS. The old code used jsonp, which works nicely, but does not support ASMX pages.
As mentioned in my comment part of the problem was Visual Studio too. VS2013 running IE11 in debug mode does not allow CORS operations. I had to launch IE11 outside of Visual Studio to get things to work along with the other changes.
Here are some links that I saw: link 1, link 2, and more importantly link 3.
Additions/changes call for in 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:
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. This header is equivalent to the PHP header.
Testing done on Win7-64 using IE11. IE11 supports CORS, as noted in one link.
(Question updated to reflect answer.)