在put方法中参数的值为null

时间:2018-07-13 18:07:47

标签: c# asp.net-core

这是模型:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace CollectionsCatalogWebAPI.Models
{
    [Table("User")]
    public class User
    {

        #region attributes

        private Int64 id;
        private String username;
        private String firstName;
        private String middleInitials;
        private String lastName;
        private String password;
        private String gender;
        private String active;

        #endregion

        #region properties

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Int64 Id
        {
            set { this.id = value; }
            get { return this.id; }

        }

        [StringLength(50)]
        public String Username
        {
            set { this.username = value; }
            get { return this.username; }
        }

        [StringLength(50)]
        public String FirstName
        {
            set { this.firstName = value; }
            get { return this.firstName; }
        }

        [StringLength(10)]
        public String MiddleInitials
        {
            set { this.middleInitials = value; }
            get { return this.middleInitials; }
        }

        [StringLength(50)]
        public String LastName
        {
            set { this.lastName = value; }
            get { return this.lastName; }
        }

        [StringLength(64)]
        public String Password
        {
            set { this.password = value; }
            get { return this.password; }
        }

        [StringLength(1)]
        public String Gender
        {
            set { this.gender = value; }
            get { return this.gender; }
        }

        [StringLength(1)]
        public String Active
        {
            set { this.active = value; }
            get { return this.active; }
        }

        #endregion

        #region especifcMethods

        /// <summary>
        /// Returns a string representation of this instance.
        /// </summary>
        /// <returns>Returns a string representation of this instance.</returns>
        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("[CollectionsCatalogWebAPI.Models.User:");
            sb.Append(" Username: ");
            sb.Append(this.Username);
            sb.Append(" FirstName: ");
            sb.Append(this.FirstName);
            sb.Append(" MiddleInitials: ");
            sb.Append(String.IsNullOrEmpty(this.MiddleInitials) ? "" : this.MiddleInitials);
            sb.Append(" LastName: ");
            sb.Append(String.IsNullOrEmpty(this.LastName) ? "" : this.LastName);
            sb.Append(" Gender: ");
            sb.Append(String.IsNullOrEmpty(this.Gender) ? "" : this.Gender);
            sb.Append(" Active: ");
            sb.Append(String.IsNullOrEmpty(this.Active) ? "" : this.Active);
            sb.Append("]");

            return sb.ToString();
        }

        #endregion
    }
}

现在在控制器上,两种方法GET都可以,但是POST无法正常工作。

using System;
using System.Collections.Generic;
using System.Linq;
using CollectionsCatalogWebAPI.Config;
using CollectionsCatalogWebAPI.Models;
using Microsoft.AspNetCore.Mvc;

namespace CollectionsCatalogWebAPI.Controllers
{
    [Produces("application/json")]
    [Route("api/Users")]
    public class UsersController : Controller
    {

        private readonly CollectionsCatalogContex context;

        public UsersController(CollectionsCatalogContex context)
        {
            this.context = context;
        }

        [HttpGet]
        public IEnumerable<User> Get()
        {
            return context.UsersModel.ToList<User>();
        }

        [HttpGet("{id}", Name = "Get")]
        [ProducesResponseType(200, Type = typeof(User))]
        [ProducesResponseType(404)]
        public IActionResult Get(Int64 id)
        {
            var user = context.UsersModel.Find(id);

            if (user == null)
            {
                return NotFound();
            }

            return Ok(user);
        }

        // POST: api/Users
        [HttpPost]
        public IActionResult Post(User u)
        {
            context.UsersModel.Add(u);
            context.SaveChanges();

            return CreatedAtRoute("Get", new { id = u.Id}, u);
        }
    }
}

当我使用Postman发布下面的json时,我收到一条SQL错误,提示“活动字段不能为空”。

{
    "Id":0,
    "Username":"TEST_POST",
    "FirstName":"POSTADO",
    "MiddleInitials":"API",
    "LastName":"PELO POSTMAN",
    "Password":"senha123",
    "Gender":"M",
    "Active":"N"
}

(没有ID信息将返回相同的错误)

但是在调试中,我看到参数User(u)为null。

我可以在ToString上看到它:

u   {[CollectionsCatalogWebAPI.Models.User: Username:  FirstName:  MiddleInitials:  LastName:  Gender:  Active: ]}

有关此的一些提示?

2 个答案:

答案 0 :(得分:2)

您必须像这样使用[FromBody]

public IActionResult Post([FromBody]User u)

通过这种方式,您可以将请求主体中的数据绑定到User对象

答案 1 :(得分:1)

为了竞争:

使用[FromBody]属性对控制器进行注释时,不需要使用[ApiController](仅在ASP.NET Core 2.1和更高版本中受支持)。这是减少操作和操作参数所需属性数量的一种便捷方法。

在其他便利方法中,还有一个ActionResult<T>类型的用于WebAPI风格的动作和控制器。

您可以从以下ASP.NET Core 2.1.0-preview1: Improvements for building Web APIs上的博客文章中获得更多信息

  

[ApiController]和ActionResult

     

ASP.NET Core 2.1引入了特定于Web API控制器的新约定,这些约定使Web API开发更加方便。可以使用新的[ApiController]属性将这些约定应用于控制器:

     
      
  • 在发生验证错误时自动以400响应-无需在操作方法中检查模型状态
  •   
  • 推断动作参数的默认设置更聪明:对于复杂类型,[FromBody],在可能的情况下为[FromRoute],否则为[FromQuery]
  •   
  • 需要属性路由-基于约定的路由无法访问操作
  •   
     

您现在还可以从Web API操作中返回ActionResult,这使您可以返回任意操作结果或特定的返回类型(由于巧妙地使用了隐式强制转换运算符)。大多数Web API操作方法都有特定的返回类型,但还需要能够返回多个不同的操作结果。