toing_toing
toing_toing

Reputation: 2452

Cannnot get JSONP response from WebAPI using jquery

I am developing a C# MVC web application that will send cross domain requests to a Web API REST Service. However I keep on getting errors. My jquery code is as follows:

$.ajax({
            url: RESTurl,
            type: 'GET',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'myCallback'
        });

        window.myCallback = function (data) {
            console.log(data);
        };

The webAPI code that is handling my request is like this:

[HttpPost, HttpGet]
        public String checkStatus(string passedId)
        {
           //some other code
           return "Status Unavailable";
        }

My webApiConfig File is as follows:

 config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{passedId}",
                defaults: new { passedId = RouteParameter.Optional }
            );
        config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html"));

My issue is that when I type the request in the browser address bar, I get the correct response- Status Unavailable. (I also get the correct response using postman, but I believe that is because CORS doesn't apply to postman)

I have tried adding crossDomain: 'true' and adding jquery cross domain plugin to the project, but it hasn't helped.

I have also tried without a callback function but I did not get a result.

Also tried adding Microsoft.AspNet.WebApi.Cors to the webApi project and then adding

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

to webApiConfig.cs (as suggested here) but it did not make a difference either. I am surprised how there would be a response when typing directly from the browser if there is an issue with CORS. My current response is like this:

http://xxxxx.com:xxxx/xerviceapi/api/xxx/checkstatus/3?callback=myCallback&_=1500087168776

Here's a screenshot: enter image description here

As you might see, my jquery version is 1.10 (little old), but I can't upgrade at the moment as other modules depend on it. Is this a reason?

Also do I need to add a response body to webAPI even though I get a response from the browser? if so how? Please help.

Upvotes: 0

Views: 1086

Answers (2)

toing_toing
toing_toing

Reputation: 2452

After a lot of trial and error and thanks to @Khanh TO and @Hugo Sama's helpful advice, I found out that the issue was with webAPI not being properly configured to add CORS headers.

It should be also noted that JSONP is a completely different concept, which is a way of bypassing CORS restrictions in browsers.

First of all, about using JSONP, it only supports GETrequests and also may not be supported by older browsers and older versions of jquery. The better option is to use regular ajax requests, which support all http request methods. Configuring webAPI to respond to CORS requests is pretty straightforward, but can appear tricky.

I will give the steps I followed. This link was very helpful.

Firstly, you need to install the package Install-Package

Microsoft.AspNet.WebApi.Cors

either from the package manager console or from nuget packet manager. Afterwards, in App_Start/WebApiConfig.cs, I added an Application_BeginStart method as follows:

protected void Application_BeginRequest()
        {
            if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
            {
                Response.Flush();
                Response.End();
            }
        }

Next, add the EnableCors attribute just before the start of your controller class as follows:

using System.Web.Http.Cors;

namespace xxxAPI.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class xxxxController : ApiController
    { //.. blah blah blah

You can also use this attribute on individual action controllers as well. The parameters can be changed as per your requirement. My code enables CORS requests from any URL, any method. Please check the link mentioned above for more info.

Finally you need to add the following lines in webconfig file under <system.webServer>.

<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="*" />
        <add name="Access-Control-Allow-Headers" value="*"/>
      </customHeaders>
    </httpProtocol>

Some sources also ask you to add:

 config.enableCors();

in WebApiConfig.cs, but this causes the webApi to send back multiple CORS headers, which causes issues with browsers. I believe you should set either the webConfig file or WebApiConfig.cs file, just one. That is all, there was no need to change the webApiConfig for me.

For completeness, here is a sample action controller method in my service which returns an httpResponseMessage.

 [HttpPost, HttpGet]
        public HttpResponseMessage stopxxxxx(string passedId)
        {
        string returnedValue = "Error Stopping xxxxx";

        return new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(returnedValue, System.Text.Encoding.UTF8, "text/plain")
        };
    }

And here is the request I am making in jquery (As you can see, it is a regular plain ajax query):

 $.ajax({
        type: 'GET',
        url: RESTurl,
    }).done(function (data) {
        //alert(data);
    }).error(function (jqXHR, textStatus, errorThrown) {
        //handle error
    });

Upvotes: 1

Hugo sama
Hugo sama

Reputation: 909

Seems like your problem may be with CORS, try adding this header to your webAPI:

Access-Control-Allow-Origin: *

Upvotes: 0

Related Questions