Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ajax post works vs. angularjs $http does not work w/ ASP.NET MVC 4

I have two projects client side and server side. Client side project is pure htmljs. Server side is ASP.NET MVC 4 and Web Api. Because there are two projects I need to enable CROS functionality. I added into server's webconfig:

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

Ajax Post version which is working:

$.post(url, appContext).done(
                function(data, textStatus, jqXHR) {
                    successFn(data, textStatus);
                })
                .fail(
                    function(jqXHR, textStatus, err) {
                        errorFn(err, textStatus);
                    });

angular $http Post version which is NOT working:

 $http({
                url: url,
                method: 'POST',
                params: { appContext: appContext },
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                    /*'Accept': 'text/json'*/}
            }).success(successFn).error(errorFn);

When I use $http I am getting two errors:

  1. OPTIONS url 405 (Method Not Allowed)
  2. POST url 500 (Internal Server Error)

ASP.NET MVC method is

[System.Web.Http.HttpPost]
public List<Module> GetModules([FromBody]SessionContext appContext)
{
 return  CreateModules();
}

EDIT:

Angular model's configuration:

var emsApp = angular.module('EmsWeb', ['ui.bootstrap']);
emsApp.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {

    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);

Headers of OPTIONS request that I see in browser:

Request URL:http://localhost/EmsWeb/api/ModuleApi/GetModules?appContext=%7B%22globalDate%22%3A%22Mon%2C%2008%20Jul%202013%2013%3A09%3A35%20GMT%22%2C%22userToken%22%3A%22AlexToken%22%7D
Request Method:OPTIONS
Status Code:405 Method Not Allowed

Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:localhost
Origin:http://localhost:50463
Referer:http://localhost:50463/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Query String Parametersview sourceview URL encoded
appContext:{"globalDate":"Mon, 08 Jul 2013 13:09:35 GMT","userToken":"AlexToken"}

Response Headers
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:76
Content-Type:application/json; charset=utf-8
Date:Mon, 08 Jul 2013 13:09:35 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

Any ideas why angular way does not work are appreciated?

Update the issue as it turns out to be quite silly: because I used params and instead of data in:

 $http({
                url: url,
                method: 'POST',
                params: { appContext: appContext },
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                    /*'Accept': 'text/json'*/}
            }).success(successFn).error(errorFn);

angular converted to GetRequest. No need for ContentType either. so actual code is

 $http({method: 'POST',
            url: url,                
            data: appCtx,
        }).success(successFn).error(errorFn);

so ALMOST resolved, I see that angular still issues OPTIONS request that fails but post request goes through...

so any ideas on that one are appreciated

like image 968
Tech Wizard Avatar asked Feb 17 '23 00:02

Tech Wizard


1 Answers

My issue were due to two reasons: I used params and instead of data in

 $http({
                url: url,
                method: 'POST',
                params: { appContext: appContext },
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                    /*'Accept': 'text/json'*/}
            }).success(successFn).error(errorFn);

angular converted to GetRequest. No need for ContentType either. so actual code is

 $http({method: 'POST',
            url: url,                
            data: appCtx,
        }).success(successFn).error(errorFn);

on the server side I needed something handling OPTIONS request. One way is to decorate method w/ [System.Web.Http.AcceptVerbs("OPTIONS")], which I do not think the best way. Another way is to add Custom Message Handler. I am still researching it...

like image 60
Tech Wizard Avatar answered Feb 18 '23 13:02

Tech Wizard