Angular POST请求到Web API无法传递数据。
Angular POST请求到Web API无法传递数据。
我一直在使用jQuery针对ASP.NET Web API编写代码,现在我开始使用Angular(仍然针对相同的Web API后端编写)。我正在向一个方法发送POST请求,该方法将返回系统中某个实体的一些搜索结果。代码如下:\n
public IEnumerablePost(string entity, FormDataCollection parameters) { // entity是通过路由传递的。 // parameters包含了我想要获取的所有内容。 }
\n如果我使用jQuery.post调用该方法:\n
$.post('api/search/child', {where : 'ParentID = 1'}, function(d){ foo = d });
\n它能正常工作并返回我期望的结果。\n我在我的Angular应用程序中创建了一个类似的服务来进行调用:\n
$http.post('api/search/child', { where: 'parentID = ' + parent.ID }) .success(function (data, status, headers, config) { // 等等。 })
\n但是当它到达服务器上的我的“Post”方法时,“parameters”是null。\n经过一些搜索后,我尝试添加content-type头来确保它以JSON格式传递,并尝试对“data”参数进行JSON.stringify和$.param()处理,但是这并没有起作用(根据我阅读的内容,这不应该是必需的)。我在这里做错了什么?谢谢您的帮助!\n更新:\n以下是(有效的)jQuery示例的原始请求:\nPOST http://localhost:51383/api/search/child HTTP/1.1\nAccept: */*\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\nX-Requested-With: XMLHttpRequest\nReferer: http://localhost:51383/mypage.aspx\nAccept-Language: en-US\nAccept-Encoding: gzip, deflate\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\nHost: localhost:51383\nContent-Length: 23\nDNT: 1\nConnection: Keep-Alive\nPragma: no-cache\nCookie: (etc)\nAuthorization: (etc)\nwhere=ParentID+%3D+1\n
\n以及(失败的)Angular示例的原始请求:\nPOST http://localhost:51383/api/search/parent HTTP/1.1\nContent-Type: application/json;charset=utf-8\nAccept: application/json, text/plain, */*\nReferer: http://localhost:51383/mypage.aspx\nAccept-Language: en-US\nAccept-Encoding: gzip, deflate\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\nConnection: Keep-Alive\nContent-Length: 27\nDNT: 1\nHost: localhost:51383\nPragma: no-cache\nCookie: (etc)\n{\"where\":\"ScorecardID = 1\"}\n
\n非常奇怪。即使我在jQuery调用的末尾添加了“json”数据类型参数,它仍然创建了www-form-urlencoded请求。而这个请求是有效的。我的Web API应用程序已经设置为JSON(感谢Dalorzo)。
问题原因:客户端使用Angular发送POST请求到Web API时,无法传递数据。
解决方法:
1. 在客户端代码中,使用$http对象发送POST请求,设置url、method、data和headers等参数。
2. 在服务器端代码中,为了允许跨域请求,需要添加一个名为AllowCrossSiteJson的自定义属性。
3. 在AllowCrossSiteJson属性的OnActionExecuting方法中,设置响应头中的Access-Control-Allow-Origin为"*",表示允许所有来源的跨域请求。
4. 在服务器端的Api方法中,使用JsonConvert.DeserializeObject方法将请求的Form数据转换为AgentRequest对象,并进行相应的处理。
以下是完整的代码:
客户端代码:
$http({ url: me.serverPath, method: 'POST', data: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, }). success(function (serverData) { console.log("ServerData:", serverData); // 其他处理逻辑 });
服务器端代码:
[AllowCrossSiteJson] public string Api() { var data = JsonConvert.DeserializeObject(Request.Form[0]); if (data == null) return "Null Request"; var bl = Page.Bl = new Core(this); return data.methodName; } public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*"); base.OnActionExecuting(filterContext); } }
通过以上代码和步骤,可以解决Angular发送POST请求到Web API时无法传递数据的问题。
原因:Angular框架使用$http.post()方法发送POST请求时,与jQuery的行为不同,不会将数据直接发送到请求体中。
解决方法:可以通过一些调整来覆盖Angular的默认行为,使其表现类似于jQuery的$.ajax()方法。
具体解决方法可以参考Victor Savkin在他的博客中提供的文章《Make AngularJS $http service behave like jQuery ajax》。在这篇文章中,他介绍了如何修改Angular的默认行为,使其能够正确地发送POST请求。
以下是解决方法的基本步骤:
1. 创建一个名为"app"的Angular模块,并指定"config"方法来配置$httpProvider。
2. 在"config"方法中,使用"$httpProvider.defaults.transformRequest"属性来重写请求的默认转换函数。
3. 在重写的转换函数中,将请求数据转换为URL编码的字符串,并将其设置为请求的content-type头部。
4. 在服务器端,使用相应的方法来解析URL编码的请求体。
以下是修改后的代码示例:
angular.module('app', []) .config(function($httpProvider) { $httpProvider.defaults.transformRequest = function(data) { if (data === undefined) { return data; } return $.param(data); }; $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; }) .controller('MyController', function($http) { var vm = this; vm.submitData = function() { var data = { name: 'John', age: 30 }; $http.post('/api/endpoint', data) .then(function(response) { console.log(response.data); }); }; });
通过以上步骤,我们可以使Angular的$http.post()方法正确地将数据发送到Web API。
问题原因:没有在配置中包含JSON格式器。
解决方法:
1. 检查是否在配置中包含JSON格式器,可以使用以下代码:
System.Web.Http.GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); config.Formatters.Insert(0, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
2. 确保设置了正确的格式器,只有这样Content-Type=application/json
才能起作用。
3. 可以尝试在参数类型旁边使用[FromBody]标记。