3

I have a ASP MVC project with some Ajax Calls, where I am trying to pass from jquery/Ajax to my AjaxController (see bellow code) where in the controller sting item is receiving a json string like this

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

And I get this error in my controller (See bellow code where the comment identifies the error)

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)

This is my Json/Jquery creation function

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);
        }
    }

And here is my controller where the error is given

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);
        }

The question would be how can I itterate that json string without receiving an error?

Ricardo Rios
  • 255
  • 7
  • 23

2 Answers2

3

Your code need a little bit of refactoring; basically you have a json structure like this one:

[
  "1002",
  "1003"
]

That is basically an Array of Strings.

In your Controller you have the following line:

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

Now, what this little chunk of code List<string[]> means? With that line you are trying to create a List of arrays of string, something like this:

[
  ["1002","1003"],
  ["1002","1003"]
]

So your deserializing methods fails with the following message: Could not cast or convert from System.String to System.String[]. Now makes sense.

So if you want to deserialize an json array of string you just needs:

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

List<string> is just like and array of string(internally a list is constructed on an array basis, check this answer for more information about array and list: Array versus List<T>: When to use which?

Based on that info you can write your code this way too:

string[] datax1 = JsonConvert.DeserializeObject<string[]>(items); //Not tested, but should works.
Community
  • 1
  • 1
Hackerman
  • 12,139
  • 2
  • 34
  • 45
0

Don't double Json encode, and let the WebAPI do all the work:

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);
        }
    }

and

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);
    }
Robert McKee
  • 21,305
  • 1
  • 43
  • 57