【问题标题】:asp.net web api - post a object to web apiasp.net web api - 将对象发布到 web api
【发布时间】:2017-09-19 13:50:03
【问题描述】:

我正在尝试将用户对象从 c# 客户端应用程序发布到 web api,该 web api 应该将新用户存储到数据库中。该模型基于同一类。目前客户端这个函数用于发帖:

public static async Task CreateNewUser(string userName, string eMail, string password, string name, string firstName)
        {
            User newUser = new User(userName, eMail, password, name, firstName);
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(restAddress);
                try
                {
                    var response = await client.PostAsync(restAddress + "api/Users", newUser);
                    response.EnsureSuccessStatusCode();
                }
                catch (Exception e)
                {

                    ExecutionConsole.WriteError(e.ToString());
                }
            }
        }

而Web API中的控制器有这个功能:

// POST: api/Users
        [ResponseType(typeof(User))]
        public async Task<IHttpActionResult> PostUser(User user)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Users.Add(user);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                if (UserExists(user.Username))
                {
                    return Conflict();
                }
                else
                {
                    throw;
                }
            }

            return CreatedAtRoute("DefaultApi", new { id = user.Username }, user);
        }

API 返回 400(错误请求)。 Web API 目前有这样的配置:

 public void Configuration(IAppBuilder appBuilder)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            appBuilder.UseWebApi(config);
        }

编辑:

用户模型:

public class User
            {
                public User(string userName, string email, string password) : this(userName, email, password, null, null)
                {

                }
                public User(string userName, string email, string password, string Name, string firstName)
                {
                    this.Username = userName;
                    this.Email = email;
                    this.Password = password;
                    this.Name = Name;
                    this.firstName = firstName;
                }

                [Key, Required]
                public string Username { get; set; }
                public string Name { get; set; }
                public string firstName { get; set; }
                [Required]
                public string Email { get; set; }
                [Required]
                public string Password { get; set; }
                public virtual ICollection<Playlist> CreatedPlaylists { get; set; }
                public virtual ICollection<Track> SavedTracks { get; set; }

            }

HTTPRequest(Rest API 是我的 Web API 项目的名称):

{Method: POST, RequestUri: 'http://localhost:2468/api/Users', Version: 1.1, Content: System.Net.Http.ObjectContent`1[[RestAPI.Model.User, RestAPI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Headers:
{
  Content-Type: application/json; charset=utf-8
  Content-Length: 143
}}
    Content: {System.Net.Http.ObjectContent<RestAPI.Model.User>}
    Headers: {}
    Method: {POST}
    Properties: Count = 0
    RequestUri: {http://localhost:2468/api/Users}
    Version: {1.1}

HTTP 内容:

{System.Net.Http.ObjectContent<RestAPI.Model.User>}
    Formatter: {System.Net.Http.Formatting.JsonMediaTypeFormatter}
    Headers: {Content-Type: application/json; charset=utf-8
Content-Length: 143
}
    ObjectType: {Name = "User" FullName = "RestAPI.Model.User"}
    Value: {RestAPI.Model.User}

编辑 #2:

响应正文:

    Id = 22, 
    Status = RanToCompletion, 
    Method = "{null}", 
    AsyncState: null
    CancellationPending: false
    CreationOptions: None
    Exception: null
    Id: 22
    Result: {Message:"The request is invalid.",
    ModelState:{"user.Username":["Unable to find a constructor to use for type ClAuP.RestAPI.Model.User. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Username', line 1, position 12."]}}"
    Status: RanToCompletion

【问题讨论】:

  • 有效载荷可能有问题。你能显示User 类和正在发送的http 请求吗?
  • 你真的在控制器中接收到用户模型吗?是否为空?您能否提供状态码为 400 的响应正文?
  • @Merchezatter 收到的模型为空。
  • 您的 User 类应该是 serializable 以便可以将其转换为字符串并在 http 中发送。这就是对象在应用程序之间传递的方式。查看 [Serializable] 属性和要序列化的特定字段。

标签: c# asp.net asp.net-web-api


【解决方案1】:

错误消息是说您需要一个默认构造函数才能反序列化对象。由于您添加了自定义构造函数,这意味着没有空的默认构造函数,除非您明确将其放在那里。所以你应该可以添加

public User() { }

到您的用户类并解决该错误。

【讨论】:

    【解决方案2】:

    为了能够序列化和反序列化一个对象,你需要一个空的构造函数。

    public class User
    {
        // Add this
        public User()
        {
        }
    
        public User(string userName, string email, string password) : this(userName, email, password, null, null)
        {
    
        }
    
        public User(string userName, string email, string password, string Name, string firstName)
        {
            this.Username = userName;
            this.Email = email;
            this.Password = password;
            this.Name = Name;
            this.firstName = firstName;
        } 
    
        [...]
    }
    

    创建User 类的实例后,它将通过公开给模型的公共属性填充模型。您已经拥有公共属性,因此添加构造函数可以解决您的问题。

    【讨论】:

    • 感谢您的回答。您的解决方案与上述相同,也是正确的。 ;)
    【解决方案3】:

    您必须将 [FromBody] 添加到您的方法中并验证您所指的 clace 没有继承“From Body”强制您读取整个正文,如果它没有找到请求的属性,则返回 NULL [响应类型(类型(用户))] 公共异步任务

    [ResponseType (typeof (User))]
    Public asynchronous task <IHttpActionResult> PostUser ([FromBody]User user)
    

    【讨论】:

      猜你喜欢
      • 2015-01-15
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多