如何使用C# ASP MVC反序列化json字符串

3

我有一个ASP MVC项目,其中包含一些Ajax调用。我尝试从jquery/Ajax传递到我的AjaxController(见下面的代码),在控制器中,字符串item接收像这样的json字符串:

"[\n  \"1002\",\n  \"1003\"\n]"

我在控制器中遇到了这个错误(请见下面代码,其中的注释标识了错误)

Newtonsoft.Json.JsonSerializationException: Error converting value "1002" to type 'System.String[]'. Path '[0]', line 2, position 9. ---> System.ArgumentException: Could not cast or convert from System.String to System.String[]. at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType) at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType) ...(continue)

这是我的Json/Jquery创建函数。
function SaveObservations() {
        var SerSel = $("#ServiceIdSelect2").val();
        var obs = $("#observation").val();
        var itemsX = [];
        if (obs == "") {
            mostrar_alert_ui("Validation message", "Observation cannot be null", 350);
        } else {
            //Start json creation
            $("#ItemsPieces > input:checked").each(function () {
                var id = $(this).val();
                itemsX.push(id);
            });
            var itemsY = JSON.stringify(itemsX, null, 2);
            //End json creation
            Funciones_Ajax_conAlert("/Ajax/SendEmailItemsToClient/", { proyecto: SerSel, items: itemsY, observation: obs }, CloseObservations);
        }
    }

以下是出错的控制器代码

public JsonResult SendEmailItemsToClient(int proyecto, string items, string observation) 
        {
            object data = null;
            try
            {

                List<string[]> datax1 = JsonConvert.DeserializeObject<List<string[]>>(items); //Here is the issue Aqui tengo el problema

                foreach (var item in datax1) 
                {
                    string test = item.ToString();
                }
                string mensaje = "";
                int ProjectIdx = proyecto;
                bool resp = CorreccionesController.SendItemsDifferentsToClient(ProjectIdx, mensaje);
                if (resp) { 
                    data = new
                    {
                        success = true,
                        titulo = "Notification",
                        mensaje = "A message explaining why the different items selected are used had been sent"
                    };
                } 
                else 
                {
                    data = new
                    {
                        success = false,
                        titulo = "Notification",
                        mensaje = "The observation is Saved but the email couldn't be send, please contact support"
                    };
                }
            }
            catch (Exception ex) 
            {
                data = new
                {
                    success = false,
                    titulo = "ERROR",
                    mensaje = ex.ToString()
                };
            }
            return Json(data, JsonRequestBehavior.AllowGet);
        }

问题是如何迭代该JSON字符串,而不产生错误?

将参数更改为 string[] items(您正在发送值数组,而不是单个值) - user3559349
List<string[]> 更改为 List<string> - Hackerman
@Hackerman 谢谢,我用你的解决方案解决了问题,你能否提供一个更完整的答案,这样我就可以接受它并给你+1? - Ricardo Rios
好的,我会尽快提供答案。 - Hackerman
@RicardoRios,已完成。请您检查我的答案。 - Hackerman
2个回答

3

您的代码需要进行一些重构;基本上您有一个像这样的json结构:

[
  "1002",
  "1003"
]

这基本上是一个字符串数组。

在您的控制器中,您有以下行:

List<string[]> datax1 = JsonConvert.DeserializeObject<List<string[]>>(items); 

现在,这个小代码块 List<string[]> 是什么意思?使用这行代码,您正在尝试创建一个字符串数组列表,类似于以下内容:
[
  ["1002","1003"],
  ["1002","1003"]
]

您的反序列化方法失败并显示如下信息:无法将System.String转换为System.String[]。现在有意义了。

因此,如果您想反序列化一个字符串的json数组,您只需要:

List<string> datax1 = JsonConvert.DeserializeObject<List<string>>(items); 

List<string>就像是一个字符串数组(在内部基于数组构建了一个列表,有关数组和列表的更多信息请查看此答案:Array versus List<T>: When to use which?

基于这些信息,您也可以这样编写代码:

string[] datax1 = JsonConvert.DeserializeObject<string[]>(items); //Not tested, but should works.

0

不要对Json进行双重编码,让WebAPI完成所有工作:

function SaveObservations() {
        var SerSel = $("#ServiceIdSelect2").val();
        var obs = $("#observation").val();
        var itemsX = [];
        if (obs == "") {
            mostrar_alert_ui("Validation message", "Observation cannot be null", 350);
        } else {
            //Start json creation
            $("#ItemsPieces > input:checked").each(function () {
                var id = $(this).val();
                itemsX.push(id);
            });

            //End json creation
            Funciones_Ajax_conAlert("/Ajax/SendEmailItemsToClient/", { proyecto: SerSel, items: itemsX, observation: obs }, CloseObservations);
        }
    }

并且

public JsonResult SendEmailItemsToClient(int proyecto, string[] items, string observation) 
    {
        object data = null;
        try
        {

            foreach (var item in items) 
            {
                string test = item.ToString();
            }
            string mensaje = "";
            int ProjectIdx = proyecto;
            bool resp = CorreccionesController.SendItemsDifferentsToClient(ProjectIdx, mensaje);
            if (resp) { 
                data = new
                {
                    success = true,
                    titulo = "Notification",
                    mensaje = "A message explaining why the different items selected are used had been sent"
                };
            } 
            else 
            {
                data = new
                {
                    success = false,
                    titulo = "Notification",
                    mensaje = "The observation is Saved but the email couldn't be send, please contact support"
                };
            }
        }
        catch (Exception ex) 
        {
            data = new
            {
                success = false,
                titulo = "ERROR",
                mensaje = ex.ToString()
            };
        }
        return Json(data, JsonRequestBehavior.AllowGet);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接