【问题标题】:Issue while binding the POSTed complex form data from Angular JS to ASP.Net Web API 2将发布的复杂表单数据从 Angular JS 绑定到 ASP.Net Web API 2 时出现问题
【发布时间】:2016-04-12 13:30:43
【问题描述】:

我正在编写一些演示示例,说明如何将表单数据从 Angular 服务传递到 Web API 2 控制器的 POST 操作。但我的对象在控制器端始终为空。这是我的代码的样子

AngularJS 调用 Web API

$http({
            method: 'POST',
            url: MyApp.rootPath + 'api/CustomerSpaSilo/SearchCustomers?nameFilter=' + nameFilter,
            data: $.param({ '': pagingVM }),
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });

pagingVM 是一个角度 $scope 对象,其中包含分页详细信息 - SortBy、CurrentPage、ItemsPerPage、SortDesc。

我的 Web API POST 方法

[HttpPost]
        [Route("SearchCustomers")]
        public HttpResponseMessage Post(string nameFilter, [FromBody] PagingViewModel pagingVM)
        {
            if (nameFilter == null)
                nameFilter = "";

            //Code Implementation
        }

PagingViewModel 类

public class PagingViewModel
    {
        public string SortBy { get; set; }

        public bool SortDesc { get; set; }

        public int CurrentPage { get; set; }

        public int TotalItems { get; set; }

        public int ItemsPerPage { get; set; }

        public int TotalPages
        {
            get {
                if (this.ItemsPerPage > 0)
                    return (int)Math.Ceiling((decimal)TotalItems / this.ItemsPerPage);
                else
                    return 1;  
            }
        }
    }

pagingVM 参数始终作为默认对象出现。快速浏览一下 Chrome 的网络活动表明所有值都作为表单数据在请求正文中传递。如果我将参数类型更改为 FormDataCollection,那么我可以读取这些值并构建我的对象,但我希望 Web API 为我绑定传入的请求值。我在这里错过了什么吗?

【问题讨论】:

  • 我很确定这个 '': pagingVM 应该读取 'pagingVM': pagingVM
  • @Kell 我也尝试过,但无济于事。事实上,这就是我最初尝试的方式。在 chrome 网络选项卡中,它显示为 pagingVM[SortBy]:CustomerID 等。我想知道它周围的方括号是否是问题所在。
  • 你可能也想要 JSON.stringify($.param({ 'pagingVM': pagingVM }))。
  • @Kell - 有效的是数据:$.param(pagingVM)。
  • 酷,很高兴你把它分类了 :)

标签: c# asp.net angularjs http-post asp.net-web-api2


【解决方案1】:

控制器

    [RoutePrefix("api/CustomerSpaSilo")]
    public class CustomerSpaSiloController : ApiController
    {
        [HttpPost]
        [Route("SearchCustomers")]
        public IHttpActionResult Post(string nameFilter, [FromBody] PagingViewModel pagingVM)
        {
            if (nameFilter == null)
                nameFilter = "";

            //Code Implementation

            return Ok("Result=" + pagingVM.ToString());
        }
    }

型号

    public class PagingViewModel
    {
        public string SortBy { get; set; }

        public bool SortDesc { get; set; }

        public int CurrentPage { get; set; }

        public int TotalItems { get; set; }

        public int ItemsPerPage { get; set; }

        public int TotalPages
        {
            get
            {
                if (this.ItemsPerPage > 0)
                    return (int) Math.Ceiling((decimal) TotalItems/this.ItemsPerPage);
                else
                    return 1;
            }
        }

        public override string ToString()
        {
            return string.Format("PagingViewModel(SortBy='{0}',SortDesc='{1}', CurrentPage='{2}', TotalItems='{3}', ItemsPerPage='{4}')",
                SortBy, SortDesc, CurrentPage, TotalItems, ItemsPerPage);
        }
    }

邮递员截图

js 客户端

<!DOCTYPE html>
<html ng-app="app">
<head>
    <title>Home</title>
</head>
<body ng-controller="HomeController">

<button ng-click="post()">post</button>
<p>{{status}}</p>
<pre>{{result | json}}</pre>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script>
    (function() {
        'use strict';

        console.trace('js loaded');

        angular
            .module('app', [])
            .factory('api', apiFactory)
            .controller('HomeController', HomeController);

        function apiFactory($http) {
            var svc = {
                searchCustomers: searchCustomers
            };
            return svc;

            function searchCustomers(nameField, paging) {
                return $http
                    .post('/api/CustomerSpaSilo/SearchCustomers?nameFilter=' + nameField,
                        paging,
                        {
                             headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                             transformRequest: function (obj) {
                                 var str = [];
                                 for (var p in obj)
                                    str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                                 return str.join("&");
                             }
                        }
                     );
            }
        }

        function HomeController($scope, api) {

            console.trace('HomeController');

            $scope.status = null;
            $scope.result = null;
            $scope.post = function () {

                var paging = {
                    SortBy: 'abc',
                    SortDesc: false,
                    CurrentPage: 3,
                    TotalItems: 52,
                    ItemsPerPage: 10
                };

                api.searchCustomers('ddd', paging)
                    .then(function(response) {
                        $scope.status = 'OK';
                        $scope.result = response.data;
                    }, function(reason) {
                        $scope.status = 'Error';
                        $scope.result = reason;
                    });
            };
        }
    })();
</script>
</body>
</html>

镀铬屏幕截图

【讨论】:

  • 感谢您的回答。我会尽力告诉你进展如何。
  • 邮递员部分有效。帮助不大。但是js客户端部分不起作用。请求负载看起来像 {"SortBy":"abc","SortDesc":false,"CurrentPage":3,"TotalItems":52,"ItemsPerPage":10} 这是不正确的。你确定 js 客户端为你工作吗?
  • 我将数据作为 data: $.param(pagingVM) 传递,它似乎有效。感谢您的回答,它帮助了我。我仍然想知道您的 js 客户端代码是否按预期工作。
  • 你是对的。我将 transformRequest 参数添加到 $http。 stackoverflow.com/questions/24710503/…
【解决方案2】:

您应该像使用 $http 服务一样 -

 $http.post(MyApp.rootPath + 'api/CustomerSpaSilo/SearchCustomers?nameFilter=' + nameFilter, pagingVM ).then(function (result) {
              //success
                }, function (data) {
               //faild
                }); 

【讨论】:

  • 它也不起作用。请求负载看起来像 {"pagingVM":{"SortBy":"CustomerID","SortDesc":false,"CurrentPage":2,"TotalItems":13,"ItemsPerPage":10,"TotalPages":2}} .此外,我想将我的数据作为表单数据发送。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2015-02-18
  • 2017-09-27
  • 1970-01-01
  • 2019-12-28
相关资源
最近更新 更多