AngularJS ngResource POST 对象在 C# Web API 中为 Null

本文关键字:Web API 中为 Null ngResource POST 对象 AngularJS | 更新日期: 2023-09-27 17:55:24

我的问题是,当我将一个完整的Javascript对象发送到我的Web API控制器时,我总是得到空值。即使我有一个完整的对象,我也需要指定每个属性和值,如下所示。如何使Web API接受现成的Javascript对象并正确绑定它?

C# Web API 控制器:

[Route("addcredentials/{salesId}")]
[HttpPost]
public IHttpActionResult AddCredentials([FromUri] int salesId, [FromBody] ScriveCredentials credentials)
{
    return Ok(credentials);
}

C# 凭据对象:

public class Credentials
{
    public string ClientIdentifier { get; set; }
    public string ClientSecret { get; set; }
    public string TokenIdentifier { get; set; }
    public string TokenSecret { get; set; }
}

传递给资源的Javascript对象,保存为"结果":

{ClientIdentifier: "a", ClientSecret: "b", TokenIdentifier: "c", TokenSecret: "d"}

资源方法:

addCredentials: {
    method: 'POST',
    url: 'api/addcredentials/:userSalesId'
}

导致空值的用法:

userResource.addCredentials({ userSalesId: user.SalesId }, { credentials: result}).$promise.then(function (data) {
    console.log(data);
});

此请求的有效负载:

{"credentials":{"ClientIdentifier":"a","ClientSecret":"b","TokenIdentifier":"c","TokenSecret":"d"}}

有效但似乎过于复杂的用法:

userResource.addCredentials({ userSalesId: user.SalesId }, { ClientIdentifier: result.ClientIdentifier, ClientSecret: result.ClientSecret, TokenIdentifier: result.TokenIdentifier, TokenSecret: result.TokenSecret }).$promise.then(function (data) {
    console.log(data);
});

请求有效负载:

{"ClientIdentifier":"a","ClientSecret":"b","TokenIdentifier":"c","TokenSecret":"d"}

更新

尝试了以下方法,但它也不起作用,所有值均为空:

addScriveCredentials: {
    method: 'POST',
    url: 'api/addcredentials/'
result.SalesId = user.SalesId;
userResource.addCredentials({}, { credentials: result }).$promise.then(function (data) {
    console.log(data);
});

C#:

[Route("addcredentials")]
[HttpPost]
public IHttpActionResult Addcredentials(Credentials credentials)
{
    return Ok(credentials);
}

AngularJS ngResource POST 对象在 C# Web API 中为 Null

我之前做过一个示例,希望下面的代码能帮助你理解。

模型。

using System.ComponentModel.DataAnnotations;
public class ProductModel
{
    public ProductModel(int id, string name, string category, decimal price)
    {
        Id = id;
        Name = name;
        Category = category;
        Price = price;
    }
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string Category { get; set; }
    [Required]
    public decimal Price { get; set; }
}

API 控制器。

using Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Hosting;
using System.Web.Http;
public class ProductsController : ApiController
{
    // other code omitted for brevity.
    [HttpPost]
    public IHttpActionResult PostProduct(ProductModel product)
    {
        try
        {
            if (product == null)
            {
                throw new ArgumentNullException("Product parameter cannot be null");
            }
            if (ModelState.IsValid)
            {
                // code omitted for brevity.
                return this.Ok();
            }
            else
            {
                throw new Exception("Product is invalid");
            }
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }
    [HttpPut]
    public IHttpActionResult PutProduct(ProductModel product)
    {
        try
        {
            if (product == null)
            {
                throw new ArgumentNullException("Product parameter cannot be null");
            }
            if (ModelState.IsValid && product.Id > 0)
            {
                // code omitted for brevity.
                return this.Ok();
            }
            else
            {
                throw new Exception("Product is invalid");
            }
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }
    // other code omitted for brevity.
}

角度服务。

// products.js
(function () {
    "use strict";
    angular
        .module("exampleApp")
        .constant("baseUrl", "http://localhost:53631/api/products/")
        .factory("productsResource", productsResource);
    productsResource.$inject = ["$resource", "baseUrl"];
    function productsResource($resource, baseUrl) {
        return $resource(baseUrl + ":id",
            {
                id: "@id"
            },
            {
                create: {
                    method: "POST"
                },
                save: {
                    method: "PUT"
                }
            });
    }
})();

角度控制器。专注于创建产品和更新以下产品功能

// edit.controller.js
(function () {
    "use strict";
    angular
        .module("exampleApp")
        .controller("EditController", EditController);
    EditController.$inject = ["$routeParams", "$location", "productsResource"];
    function EditController($routeParams, $location, productsResource) {
        var vm = this;
        vm.currentProduct = null;
        vm.createProduct = createProduct;
        vm.updateProduct = updateProduct;
        vm.saveEdit = saveEdit;
        vm.cancelEdit = cancelEdit;
        if ($location.path().indexOf("/edit/") === 0) {
            var id = $routeParams.id;
            productsResource.get({ id: id }, function (data) {
                vm.currentProduct = data;
            });
        }
        function cancelEdit() {
            $location.path("/list");
        }
        function updateProduct(product) {
            product.$save().then(function () {
                $location.path("/list");
            });
        }
        function saveEdit(product) {
            if (angular.isDefined(product.id)) {
                vm.updateProduct(product);
            } else {
                vm.createProduct(product);
            }
            vm.currentProduct = {};
        }
        function createProduct(product) {
            new productsResource(product).$create().then(function (newProduct) {
                $location.path("/list");
            });
        }
    }
})();

您可以传递一个对象作为帖子消息的正文。

添加这样的类

public class addCredentialObj
{
    public int salesId { get; set; }
    public Credentials credentials { get; set; }
}

像这样修改你的控制器(FromBody 的使用可以在这里阅读)

[Route("addcredentials")]
[HttpPost]
public IHttpActionResult AddCredentials([FromBody]addCredentialObj obj)
{
    return Ok(credentials);
}

在客户端中,您需要创建一个与 addCredentialObj 类匹配的 json 对象

var yourCredentials = {"ClientIdentifier":"a","ClientSecret":"b","TokenIdentifier":"c","TokenSecret":"d"};
var jsonData = {
    salesId: yourId,
    credentials: yourCredentials
};

然后在对控制器的$http请求中,字符串化 json 对象

$http({
    method: 'POST',
    url: 'api/addcredentials',
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json'
    },
    data: JSON.stringify(jsonData),
});