5

I've been writing code against ASP.NET Web API for a while now with jQuery and I'm starting something new in Angular (writing against the same Web API backend.)

I'm POSTing to a method that will return some search results for an entity in the system. It looks like this:

public IEnumerable<dynamic> Post(string entity, FormDataCollection parameters)
{
    // entity is passed on the route.
    // parameters contains all the stuff I'm trying to get here.
}

If I call the method using jQuery.post:

$.post('api/search/child', {where : 'ParentID = 1'}, function(d){ foo = d });

it works just right and returns what I would expect.

I've made a service in my angular application that makes a similar call:

$http.post('api/search/child', { where: 'parentID = ' + parent.ID })
.success(function (data, status, headers, config) {
    // etc.
})

But when it hits my "Post" method on the server, "paramters" is null.

After some googling I've tried adding a content-type header to ensure it's passed as JSON, and trying JSON.stringify-ing and $.param()-ing the "data" argument, but that didn't do anything (and from what I've read that shouldn't be necessary.) What am I doing wrong here? Thanks for your help!

UPDATE: Here's the raw request from the (working) jQuery example:

POST http://localhost:51383/api/search/child HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://localhost:51383/mypage.aspx
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: localhost:51383
Content-Length: 23
DNT: 1
Connection: Keep-Alive
Pragma: no-cache
Cookie: (etc)
Authorization: (etc)

where=ParentID+%3D+1

And the raw request from the (failing) Angular sample:

POST http://localhost:51383/api/search/parent HTTP/1.1
Content-Type: application/json;charset=utf-8
Accept: application/json, text/plain, */*
Referer: http://localhost:51383/mypage.aspx
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
Content-Length: 27
DNT: 1
Host: localhost:51383
Pragma: no-cache
Cookie: (etc)

{"where":"ScorecardID = 1"}

Very weird. Even when I add the 'json' data type parameter to the end of the jQuery call, it still creates the www-form-urlencoded request. And that's the one that works. My Web API application is already set up for JSON (but thank-you Dalorzo).

3 Answers 3

3

Check if you have included the JSON Formatter in your configuration. It should be something like :

    System.Web.Http.GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
    config.Formatters.Insert(0, new System.Net.Http.Formatting.JsonMediaTypeFormatter());

The Content-Type=application/json only will work if you set the proper formatter.

You can also try using [FromBody] next to your parameter type.

Sign up to request clarification or add additional context in comments.

Comments

2

Solved! Discovered this question:

AngularJs $http.post() does not send data

Pointing to this lovely article:

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

Turns out Angular doesn't post data the same way jQuery does but you can override it with some tweaking.

Comments

2

I solved this by below codes:

Client Side:

     $http({
                url: me.serverPath,
                method: 'POST',
                data: data,
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            }).
                success(function (serverData) {
                    console.log("ServerData:", serverData);
    ......

Notice that data is an object.

On the server (ASP.NET MVC):

[AllowCrossSiteJson]
        public string Api()
        {
            var data = JsonConvert.DeserializeObject<AgentRequest>(Request.Form[0]);
            if (data == null) return "Null Request";
            var bl = Page.Bl = new Core(this);

            return data.methodName;
        }

and 'AllowCrossSiteJsonAttribute' is needed for cross domain requests:

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.