【问题标题】:"Type System.String is not supported for deserialization of an array" error using JSON.stringify使用 JSON.stringify 的“类型 System.String 不支持数组的反序列化”错误
【发布时间】:2020-03-24 18:22:19
【问题描述】:

为了响应按钮单击,我收集了一些用户提供的数据并将其传递给 Web 方法进行处理。

当此映射具有简单变量时,它可以正常工作(int、string 等),但现在我添加了两个对象数组并遇到了问题。我得到“消息:类型 System.String 不支持数组的反序列化”。我在 C# Web 应用程序(VS 2017)中使用 JSON.Net。

这是我目前所拥有的:

var admins = [];
var departments = [];

在某些时候,这些数组将包含一组对象,例如部门名称、首字母缩写词的行,或者在“管理员”的情况下,将包含用户 ID、姓氏等行。

$(document).on("click", "#btnAdd", function (event) {
    ...
    var newMapping = {
        orgName: orgName,
        orgAcronym: acronym,
        admins: admins,
        depts: departments
    }
    addNewOrg(newMapping, "oMapping");
    ...
});

function addNewOrg(newMapping, jsonObjName) {
    $.ajax({
        url: "../WebService/Blah.asmx/AddOrganization",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: "{" + jsonObjName + ":" + JSON.stringify(newMapping) + "}",  // This is where it throws up!
    }).done(function (result) {
        if (!result || result.d === "") {
        }
        else {
            var jResult = result.d;
            if (jResult == "-1") {
            }
            else {
            }
        }
    }).fail(function (jqXHR, textStatus, errorThrown) {
    });  
    return false;
}

网络方式:

[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]

public string AddOrganization(Dictionary<string, string> oMapping)
{
    string JSONresult = string.Empty;
    var ErrorData = new object();

    if (oMapping.Count == 0)
        return JSONresult;

    Organization oOrg = new Organization();
    try
    {
        oOrg.OrganizationName = oMapping["orgName"].ToString();
        oOrg.Acronym = oMapping["orgAcronym"].ToString();

        //JSONresult = AddOrganization(oOrg);
    }
    catch (Exception ex)
    {
        ErrorData = new
        {
            Success = "false",
            Error = "Internal error: " + ex.Message
        };
        JSONresult = JsonConvert.SerializeObject(ErrorData);
    }
    return JSONresult;
}

更新:

当我使用“调试器”跟踪代码并在“addNewOrg”函数中放置一个断点时,我可以看到“newMapping”包含:

orgName="Organization1"
orgAcronym="ORG1"
admins = [[object Object], [object Object]]  // I added two users
depts = [[object Object], [object Object]]   // I added two departments

然后,当我检查 JSON.stringify(newMapping) 时,它包含:

"{\"orgName\":\"ORGANIZATION1\",\"orgAcronym\":\"ORG1\",\"admins\":[{\"fn\":\"John\",\"mi\":\"\",\"ln\":\"Doe\",\"email\":\"John.Doe@blah.com\",\"userid\":\"ABCDE\",\"userType\":4},{\"fn\":\"Jane\",\"mi\":\"\",\"ln\":\"Doe\",\"email\":\"Jane.Doe@blah.com\",\"userid\":\"FGHIJ\",\"userType\":4}],\"depts\":[{\"dn\":\"Department1\",\"ac\":\"DPT1\"},{\"dn\":\"Department2\",\"ac\":\"DPT2\"}]}"

所以,在我看来,JSON.Stringify 并不是罪魁祸首。但它会跳过“完成”并进入“失败”。我认为这可能是“Dictionary oMapping”的网络方法签名。

【问题讨论】:

    标签: c# jquery asp.net json.net


    【解决方案1】:

    是的,方法签名是问题所在。添加 admins 和 depts 之前的 JSON 是一个简单对象,其中所有值都是字符串。现在其中两个值是数组,它不能再反序列化为Dictionary&lt;string, string&gt;。您可以尝试将其更改为Dictionary&lt;string, object&gt;,但实际上更好的解决方案是在 C# 中创建数据传输对象 (DTO) 类以适应您发送的数据。您的 DTO 的属性名称需要与您发送的 JSON 中的属性名称相匹配。类名可以是任何你想要的。

    根据您的示例 JSON,这样的事情应该可以工作:

    public class OrgDTO
    {
        public string orgName { get; set; }
        public string orgAcronym { get; set; }
        public List<AdminDTO> admins { get; set; }
        public List<DeptDTO> depts { get; set; }
    }
    
    public class AdminDTO
    {
        public string fn { get; set;}
        public string mi { get; set; }
        public string ln { get; set; }
        public string email { get; set; }
        public string userid { get; set; }
        public int userType { get; set; }
    }
    
    public class DeptDTO
    {
        public string dn { get; set; }
        public string ac { get; set; }
    }
    

    然后更改您的方法签名以接受“根”DTO,在此示例中为 OrgDTO:

    public string AddOrganization(OrgDTO orgDto)
    {
        ...
    }
    

    显然,您还需要调整方法内的代码,因为您将不再使用Dictionary&lt;string, string&gt;。

    【讨论】:

    • 谢谢。我确实将其更改为 并且可以输出简单的 (orgName, orgAcronym) 但不知道如何访问对象数组。我会试试这个建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 2014-10-28
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多