.NET Web API将JSON反序列化为对象

时间:2014-01-11 09:07:42

标签: asp.net-mvc json knockout.js

我超越了一家公司为我们开发的项目,不幸的是我们得不到多少支持,从长远来看,我们应该为自己完成维护。该应用程序包含一个简单的Web客户端(HTTP,JavaScript,Knockout Framework)和一个REST API服务(我认为是.NET 4.5,ASP.NET MVC)。

目前我只修改客户端,因此服务器仍应按预期工作。

在客户端,我稍微修改了Knockout View Model(添加了一些可计算项和一些值的优化表示)。视图模型由“问题”和“评论”组成(作为问题的数组,实际上是一个Bug跟踪器)。如果我创建了一个新问题,则会将描述添加到第一个注释中,整个Model是JSON.stringified,并且发送到.NET API服务。我与Firebug一起证明,发布的JSON看起来像这样:

{
   "Id":0,
   "Title":"THis is a title",
   "Comments":[
       {
          "Id":1,
          "Text":"this is the first comment"
       }
   ]
}

在客户端,我有一个“IssueController”:

[HttpPost]
public HttpResponseMessage PostIssues( Issue issue ) {
   //issue should already hold the deserialized content of the JSON here,
   //but it only contains 'Id' and 'Title' not the 'Comments' (empty List)
   ...
}

问题域模型对象还有一个用于保存注释的数组,但为此它已经为空。 .NET代码没有明确解析JSON的任何部分,据我所知,MVC框架通过相同的属性名称隐含地执行此操作(是吗?)。

反序列化已经按预期工作了,所以.NET代码应该没问题,但我看起来像是以某种方式修改了JSON,这种注释的隐式映射不再起作用了。不幸的是,我没有很多.NET MVC框架的经验(或者它只是.NET WebAPI框架,甚至不能告诉你)。

这些是我的问题:

  1. 那是什么类型的.NET REST API框架?我该如何区分?
  2. 这种隐式JSON反序列化是如何工作的,以及它的缺陷是什么,例如当JSON的某些部分未按预期反序列化时?特别是在客户端(正如我所说,我没有修改服务器代码)
  3. 关于我可以对JSON做什么的任何想法,服务器不再喜欢它了? ;)

  4. 修改

    Issue.cs看起来像这样(当然简化):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Bo;
    using Projects.DomainObjects;
    
    namespace Projects.Models {
    
    
    public class Issue : DomainObject {
    
        public Issue() {
    
            this.Comments = new List<Comment>();
        }
    
        public long Id { get; set; }
    
        private string _Title;
        public string Title { get { return _Title; } set { _Title = value; NotifyChanged(); } }
    
        public List<Comment> Comments { get; set; }
    }
    

    Comment.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using Common;
    using Projects.DomainObjects;
    
    namespace Projects.Models {
    
    
    public class Comment : DomainObject {
    
        public Comment() {
    
        }
    
        public long Id { get; set; }
        public string Text { get; set; }
    }
    

2 个答案:

答案 0 :(得分:2)

我只是直接从你的帖子尝试你的代码,它对我有用。

因此,您可能会遇到一些问题:

  • 将对象发布到服务器时,请确保从Knockout observable转换回json对象。因此,在您的ajax请求中,请确保它看起来像:data: ko.toJSON(issue)而不只是data: issue
  • 将对象发布到服务器时,请确保已发送标题content-type: application/json

以下是您的其他问题的答案:

那是什么类型的.NET REST API框架?我怎么能区分?

这看起来不像任何自定义(至少,你发布的内容)它只是.NET中的直接Web API。

这种隐式JSON反序列化是如何工作的,以及它的缺陷是什么,例如当JSON的某些部分未按预期反序列化时?特别是在客户端(正如我所说,我没有修改服务器代码)

服务器上的反序列化使用基于客户端设置的content-type工作的格式化程序集合。如果您想要自定义它,但有信息here

,这可能会变得复杂

关于我可以对JSON做什么的任何想法,服务器不再喜欢它了? ;)

正如我所说,你的代码对我有用!

答案 1 :(得分:2)

解决了它,问题是一个计算,返回一个排序的注释数组。所以我的淘汰模型包含

self.Comments = ko.observableArray([]); //...which gets filled with the comments of an issue

self.CommentsSorted = ko.computed(function() {...}); //...which simply returns a sorted Comments array

因此,当我序列化此模型时,发布的JSON现在代表Comments数组,但也代表CommentsSorted数组。只有在我做的时候

var i = ko.toJS(issue);
delete i.CommentsSorted;

在我发布i作为数据之前,.NET能够正确地反序列化Comments

关于这一点的神秘之处在于,我的挖空模型中总有其他计算字段,它们完全被.NET忽略,并且不会以任何方式干扰反序列化。所以它似乎主要取决于模型中字段的名称和类型(也许如果第一个字母相等?)。

好事:它现在有效 糟糕的事情:.NET对JSON数据的反序列化是如何确定的,如果它没有按预期运行,我也无法进行调试。