如何正确使用javascript反序列化将json字符串转换为复杂对象?

Posted

技术标签:

【中文标题】如何正确使用javascript反序列化将json字符串转换为复杂对象?【英文标题】:How to properly use javascript deserialization to convert a json string to a complex object? 【发布时间】:2011-12-14 23:44:09 【问题描述】:

我的 .ashx 处理程序 (var items=) 中有以下可用的 json 对象:

"Coverages":"PersonID":10,"DetCode":"","Reimbursement":"","Deductible":"","MaximumPerAnnum":"","MaximumPerVisit":"","MaximumPerVisits":"","SvcCode":"","CoverageCombinedMaximums":"PersonID":10,"DetCode":["AAAAA","BBBBB","CCCCC"],"MaximumPerAnnum":"" 

public void ProcessRequest (HttpContext context) 
        bool isSuccessful = true;

        var items = context.Request.Params["items"];
        if (isSuccessful)
        

            javascriptSerializer ser = new JavaScriptSerializer();
            AdditionalCoveragesPackage package = ser.Deserialize<AdditionalCoveragesPackage>(items);


        
        else
        
            SendErrorMessage(context);
            return;
         
    

这是我要反序列化的类的结构:

public class AdditionalCoverage

    public int PersonID  get; set; 
    public string DetCode  get; set; 
    public decimal? Reimbursement  get; set; 
    public decimal? Deductible  get; set; 
    public decimal? MaximumPerAnnum  get; set; 
    public decimal? MaximumPerVisit  get; set; 
    public int? MaximumPerVisits  get; set; 
    public string SvcCode  get; set; 

    public AdditionalCoverage()
    
    


public class AdditionalCoverageCombinedMaximum

    public int PersonID  get; set; 
    public string SvcCode  get; set; 
    public decimal? MaximumPerAnnum  get; set; 
    public List<string> DetCode  get; set; 

    public AdditionalCoverageCombinedMaximum()
    
    


public class AdditionalCoveragesPackage

    public List<AdditionalCoverage> Coverages  get; set; 
    public List<AdditionalCoverageCombinedMaximum> CoverageCombinedMaximums  get; set; 

    public AdditionalCoveragesPackage()
    
    

    public AdditionalCoveragesPackage(AdditionalCoverage coverage, AdditionalCoverageCombinedMaximum maximum)
    
        List<AdditionalCoverage> coverages = new List<AdditionalCoverage>();
        coverages.Add(coverage);
        Coverages = coverages;

        List<AdditionalCoverageCombinedMaximum> maximums = new List<AdditionalCoverageCombinedMaximum>();
        maximums.Add(maximum);
        CoverageCombinedMaximums = maximums;
    

    public AdditionalCoveragesPackage(List<AdditionalCoverage> coverages, List<AdditionalCoverageCombinedMaximum> maximums)
    
        Coverages = coverages;
        CoverageCombinedMaximums = maximums;
    

编辑:这是我需要更正的客户端方法:

function saveCoverageDetails() 
                var handler = "HttpHandlers/UpdateAdditionalCoverageDetailsHandler.ashx";
                var coverages =  PersonID: personId, DetCode: "", Reimbursement: "", Deductible: "", MaximumPerAnnum: "", MaximumPerVisit: "", MaximumPerVisits: "", SvcCode: "" ;
                var maximums =  PersonID: personId, DetCode: ["ACUPUN", "PODIAT", "OSTEOP"], MaximumPerAnnum: "" ;
                var obj =  Coverages: coverages, CoverageCombinedMaximums: maximums ;


                var data = ( items: JSON.stringify(obj) );
                callHandler(handler, data, saveSuccessful, failure);

            
   function callHandler(handler, obj, onSuccess, onFail) 

                $.ajax(
                    type: "POST",
                    url: handler,
                    data: obj,
                    dataType: "json",
                    success: onSuccess,
                    fail: onFail

                );

            

当我使用 javascript 序列化程序时,它确实返回了我的 AdditionalCoveragesPackage 对象 - 但是 - 这两个属性:Coverages 和 CombinedMaximums 都是空的。如何让它正确反序列化我的 json 字符串?

【问题讨论】:

如果您只传递一项,为什么还要使用列表? 我可以通过多个。我正在测试它 - 即一个列表:) 【参考方案1】:

在您的 JSON 字符串中,CoveragesCoverageCombinedMaximums 是简单的对象,而不是数组,所以:

public class AdditionalCoveragesPackage

    public AdditionalCoverage Coverages  get; set; 
    public AdditionalCoverageCombinedMaximum CoverageCombinedMaximums  get; set; 

也在您的示例 JSON 中:

"MaximumPerAnnum":""

所以请确保将相应的属性定义为可为空的小数:

public decimal? MaximumPerAnnum  get; set; 

否则反序列化器会崩溃。

【讨论】:

感谢您捕获可为空的小数(投票赞成您的答案)。 AdditionalCoveragesPackages 可以是两个对象的列表。我的对象的客户端构造似乎是问题所在。我已经发布了,看看你是否能从语法上发现我缺少的东西。 结束了 json 字符串被破坏,因为我使用字符串而不是零来表示可空小数。炸鸡脑!!!【参考方案2】:

JSON 中的 CoveragesCombinedMaximums 属性是对象,而不是数组。 您应该将它们更改为数组或将您的 C# 类更改为不使用 List&lt;T&gt;s。

【讨论】:

你让我走在了正确的轨道上(所以我投了赞成票)。我的对象的客户端构造似乎是问题所在。我已经发布了,看看你是否能从语法上发现我缺少的东西。 您缺少一个数组(例如,[ 1, 2, 3] 在哪里?这就是我迷路的地方。当我更改我的客户端脚本时(用 [] 包围覆盖范围和最大值 - 我在 ashx 中的项目返回 null .... 你想要var coverages = [ ... , ... , ... ] 如果我将覆盖范围和最大值更改为:var coverages = [ PersonID: personId, DetCode: "", Reimbursement: "", Deductible: "", MaximumPerAnnum: "", MaximumPerVisit: "", MaximumPerVisits:“”,SvcCode:“”, PersonID:personId,DetCode:“”,报销:“”,免赔额:“”,MaximumPerAnnum:“”,MaximumPerVisit:“”,MaximumPerVisits:“”,SvcCode:“” ]; var maximums = [ PersonID:personId,DetCode:[“ACUPUN”,“PODIAT”,“OSTEOP”],MaximumPerAnnum:“”, PersonID:personId,DetCode:[“ACUPUN”,“PODIAT”,“OSTEOP” ],MaximumPerAnnum: "" ];我的 ashx 中的项目为空..【参考方案3】:

SLAKS 和 Darin Dimitrov 都帮了大忙。如果我按如下方式编写我的 JSON 字符串(我的数组结构不正确并且为我的数字类型传递空字符串而不是零),它最终会起作用。这是更正后的客户端代码:

 var handler = "HttpHandlers/UpdateAdditionalCoverageDetailsHandler.ashx";
                var coverages = [ PersonID: personId, DetCode: "", Reimbursement: 0, Deductible: 0, MaximumPerAnnum: 0, MaximumPerVisit: 0, MaximumPerVisits: 0, SvcCode: "" ,  PersonID: personId, DetCode: "CHIROP", Reimbursement: 0, Deductible: 0, MaximumPerAnnum: 0, MaximumPerVisit: 0, MaximumPerVisits: 0, SvcCode: ""];
                var maximums = [ PersonID: personId, DetCode: ["ACUPUN", "PODIAT", "OSTEOP"], MaximumPerAnnum: 0 ,  PersonID: personId, DetCode: ["ACUPUN", "PODIAT", "OSTEOP"], MaximumPerAnnum: 0];
                var obj =  Coverages: coverages, CoverageCombinedMaximums: maximums ;

                var data = ( items: JSON.stringify(obj) );
                callHandler(handler, data, saveSuccessful, failure);

【讨论】:

以上是关于如何正确使用javascript反序列化将json字符串转换为复杂对象?的主要内容,如果未能解决你的问题,请参考以下文章

在反序列化期间将 JSON 日期转换为 .NET DateTime 的正确方法

如何将 JSON 反序列化为正确类型的对象,而无需事先定义类型?

如何序列化和反序列化 JavaScript 对象?

如何使用 Newtonsoft.Json 正确反序列化数组中的嵌套对象? [复制]

如何使用 Google 的 Gson API 正确反序列化 JSON?

将 false 反序列化为 null (System.Text.Json)