Angular POST для Web API не передает данные

Я писал код в ASP.NET Web API некоторое время с помощью jQuery, и я начинаю что-то новое в Angular (записывая на тот же бэкэнд веб-интерфейса).

Я отправляю метод, который возвращает некоторые результаты поиска для объекта в системе. Это выглядит так:

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.
}
</dynamic>

Если я вызываю метод с помощью jQuery.post:

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

он работает правильно и возвращает то, что я ожидаю.

Я сделал службу в своем приложении Angular, которое делает аналогичный вызов:

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

Но когда он нажимает мой метод "Почта" на сервере, "paramters" имеет значение null.

После некоторых поисковых запросов я попытался добавить заголовок типа контента, чтобы убедиться, что он передан как JSON, и пытается использовать JSON.stringify и $.param() - аргумент "data", но этого не делал ничего (и из того, что я читал, что не нужно.) Что я здесь делаю неправильно? Спасибо за вашу помощь!

UPDATE: Здесь необработанный запрос из (рабочего) примера jQuery:

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

И необработанный запрос из образца (неудачного) Angular:

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"}

Очень странно. Даже когда я добавляю параметр типа данных "json" в конец вызова jQuery, он все равно создает запрос www-form-urlencoded. И это тот, который работает. Приложение Web API уже настроено для JSON (но спасибо Далорзо).

3 ответа

Решено! Обнаружил этот вопрос:

AngularJs $http.post() не отправляет данные

Указывая на эту прекрасную статью:

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

Выключает Angular не отправляет данные так же, как это делает jQuery, но вы можете переопределить его с некоторой настройкой.


Проверьте, включили ли вы JSON Formatter в своей конфигурации. Это должно быть что-то вроде:

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

Content-Type=application/json будет работать, только если вы установите правильный форматтер.

Вы также можете попробовать использовать [FromBody] рядом с вашим типом параметра.


Я решил это ниже:

Сторона клиента:

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

Обратите внимание, что данные являются объектами.

На сервере (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;
 }
</agentrequest>

и 'AllowCrossSiteJsonAttribute' необходим для запросов междоменных доменов:

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

licensed under cc by-sa 3.0 with attribution.