Ошибка «Тип System.String не поддерживается для десериализации массива» с использованием JSON .stringify - PullRequest
1 голос
/ 24 марта 2020

В ответ на нажатие кнопки я собираю некоторые предоставленные пользователем данные и передаю их веб-методу для обработки.

Когда в этом отображении есть простые переменные, оно работает нормально (int, string, et * 1025). *.) но сейчас я добавляю два массива объектов и сталкиваюсь с проблемой. Я получаю «Сообщение: Тип System.String не поддерживается для десериализации массива». Я использую JSON. Net в веб-приложении C# (VS 2017).

Это то, что у меня есть:

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

В какой-то момент, эти массивы будут иметь набор объектов, таких как строки DepartmentName, аббревиатура или, в случае «admin», будут строки userID, lastName и т. д. c.

$(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 это виновник. Но он пропускает «Готово» и переходит в «Неудача». Я думаю, что это может быть подпись веб-метода словаря oMapping».

1 Ответ

0 голосов
/ 24 марта 2020

Да, проблема заключается в сигнатуре метода. JSON, который вы имели до добавления admins и depts, был простым объектом, в котором все значения были строками. Теперь, когда два значения являются массивами, его нельзя десериализовать в Dictionary<string, string>. Вы можете попробовать изменить его на Dictionary<string, object>, но на самом деле лучшее решение - создать классы Data Transfer Object (DTO) в C#, чтобы соответствовать отправляемым данным. Имена свойств ваших 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; }
}

Затем измените сигнатуру вашего метода, чтобы принять "root "DTO, который в данном примере равен OrgDTO:

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

Очевидно, что вам также потребуется скорректировать код внутри метода, поскольку вы больше не будете работать с Dictionary<string, string>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...