【问题标题】:Web API - Cannot de-serialize request objectWeb API - 无法反序列化请求对象
【发布时间】:2015-05-14 16:18:56
【问题描述】:

我正在尝试创建一个快速应用程序来尝试使用 Web API 学习 AngularJS(我使用过 ASP.NET MVC,但没有机会使用 Web API)服务器端,但我似乎无法让我的对象发布 Web API 方法时进行序列化。

我的对象是一个简单的用户对象,它继承自 BaseEntity 对象:

 public class User : BaseEntity
{
    /// <summary>
    /// Gets or sets the name.
    /// </summary>
    /// <value>
    /// The name.
    /// </value>
    public string Name { get; set; }
    /// <summary>
    /// Gets or sets the email.
    /// </summary>
    /// <value>
    /// The email.
    /// </value>
    public string Email { get; set; }

    /// <summary>
    /// Gets or sets the password.
    /// </summary>
    /// <value>
    /// The password.
    /// </value>
    public string Password { get; set; }

}

public class BaseEntity : MongoRepository.Entity, Interfaces.IEntity
    {
        /// <summary>
        /// Gets or sets the id for this object (the primary record for an entity).
        /// </summary>
        /// <value>
        /// The id for this object (the primary record for an entity).
        /// </value>
        public new int Id { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="BaseEntity"/> is selected.
        /// </summary>
        /// <value>
        ///   <c>true</c> if selected; otherwise, <c>false</c>.
        /// </value>
        public bool Selected { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="BaseEntity"/> is deleted.
        /// </summary>
        /// <value>
        ///   <c>true</c> if deleted; otherwise, <c>false</c>.
        /// </value>
        public bool Deleted { get; set; }
    }

我最近的方法尝试如下:

 public HttpResponseMessage Post(JObject user)
    {
        User userObject = user.ToObject<User>();
        _Repo.Add(userObject);

        return Request.CreateResponse(HttpStatusCode.Created, "User Created");
    }

我的 AngularJS sn-p 以更清楚地了解从 UI 发布的内容(属性是使用 ng-model 设置的,我可以看到它们是通过 Fiddler 传递的,即使 Web API 方法将这些属性反序列化为null 而不是 ""):

      $scope.User = {
      Name: '',
      Password: '',
      Email: '',
  }
  $scope.register = function () {
          $http({
              method: 'POST',
              url: '/api/User/',
              data: $scope.User //Also tried JSON.stringify($scope.User)
          })
            .success(function () {
                //Handle successful registration
            })
            .error(function () {
                //Show error message
            });
  }

调试时,我可以看到用户参数已经填充了一个对象。我尝试在请求期间设置所有属性,只有一个属性等,并通过 POSTman 和应用程序调用了 api,无论我使用哪种方式,当我尝试将用户参数对象解析为我的用户对象时,我得到一个空白用户对象.当我将参数类型作为我的用户对象时,我也会得到相同的结果。

我环顾四周,大多数示例和回答的问题都没有继承自任何东西,并且我尝试了不同的 Content-Type 认为这可能是问题所在(这是当我拥有 User 对象类型和方法)。

当涉及到从其他类派生的对象时,JSON.NET/内置 Web API 反序列化是否缺少一个怪癖,或者我缺少什么?

编辑:我已经从我的对象中删除了所有继承,并且它按我的预期绑定,所以我不确定为什么当有任何类型的继承时它不起作用。当一个对象从另一个对象继承时,是否需要进行一些设置才能使参数绑定起作用?:

public class User
{
    public string Name { get; set; }

    public string Email { get; set; }

    public string Password { get; set; }

}

【问题讨论】:

    标签: json angularjs asp.net-web-api


    【解决方案1】:

    我认为 WebAPI 足够聪明,可以直接绑定到类型化对象。所以该方法可以只采用User 类型而不是JObject

    此外,请确保 Javascript 中的属性名称也与模型的属性名称完全匹配。否则它将使用默认值对传入的模型进行水合,这对布尔值很危险!

    可能是路由。不要忘记 WebApi 中的默认路由包括 '/api/' ("api/{controller}/{id}"),而 MVC 中没有?

    没有更多细节。我只能说这些了。

    【讨论】:

    • 感谢您的cmets,我一开始直接将我的Web API方法参数作为User对象尝试过,但仍然以空白对象结束,所以将其更改为JObject以确保我正在按预期接收数据。我已经用传递的 AngularJS 范围对象修改了我原来的问题
    • 如果您直接使用 HTTP 服务,则需要将 content-type 标头设置为 application/json... 我建议改用 $http.post() 方法,因为这设置了所有明智的为你默认。然后你只需要将 URL 和数据指定为 js 对象。
    • 我已经尝试过使用 $http 和 $http.post 得到相同的结果。通过 Fiddler 检查调用时,我可以看到它们的内容类型均为 application/json
    • 我已经从我的对象中删除了所有继承,并且它正确绑定,但这不是我想做的事情。我已经用这些信息修改了我原来的问题,但仍然需要答案
    • Ok... 奇怪... 我之前在序列化器中使用过类层次结构,我敢肯定... 可能查看 DTO 模式 (en.wikipedia.org/wiki/Data_transfer_object)。这可能是您将应用程序服务边界与模型分开所需要的。
    【解决方案2】:

    我终于设法解决了我的问题,但我不知道为什么我需要这样做,而我看到的这么多示例都不需要它!无论如何,我已经用以下属性装饰了我的 User 对象和 BaseEntity:

    [JsonObject(MemberSerialization.OptOut)]
    

    这些对象是否存在于它们自己的类库中,而不是位于 Models 文件夹中?我不知道,但无论哪种方式似乎都可以解决它,然后我可以将用户类型作为我的参数类型

    【讨论】:

      猜你喜欢
      • 2016-05-16
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      相关资源
      最近更新 更多