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);
}
我之前做过一个示例,希望下面的代码能帮助你理解。
模型。
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),
});