Question

I've been trying a lot of possible solutions and none of them worked, i have something like this, but i don know if the json structure is correct, or i'am not sending it correctly to the server side, i'd like to know where is the source of the problem. This is the error: No parameterless constructor defined for type of 'System.String[]'.

Client-Side

function upload() {

    var title = [];

    var files = $('#myfile').prop("files");
    var names = $.map(files, function (val) { return val.name; });

    for (var i = 0; i < names.length; ++i) {
        var item = { 'titulo' : names[i] };
        title.push(item);
    }

    var myJSON = JSON.stringify({ titulos: title });

    console.log(myJSON);

    $.ajax({
        async: true,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: "POST",
        data: myJSON,
        url: "../handlers/saveUpload.ashx",
        success: function (msg) {
            $("#title").val("Sucesso");
            $("#msg").val("Upload efectuado com sucesso.");
            $("#alerta").show();
            $("#gif").hide();
        }
    });
}

Server-Side

try
{
    date = DateTime.Now.ToShortDateString();
    sessao = int.Parse(context.Session["userid"].ToString());

    context.Response.ContentType = "application/json";
    var data = context.Request;
    var sr = new StreamReader(data.InputStream);
    var stream = sr.ReadToEnd();

    var javaScriptSerializer = new JavaScriptSerializer();

    var arrayOfStrings = javaScriptSerializer.Deserialize<string[]>(stream);

    foreach (var item in arrayOfStrings)
    {
        context.Response.Write(item.ToString());
    }
}
catch (Exception msg) { context.Response.Write(msg.Message); }
Was it helpful?

Solution

string[] is not a valid generic type for that operation; string doesn't have a parameterless constructor so when the serialiser tries to new one up, it fails. Besides, you already have a string from sr.ReadToEnd() so you're not really deserialising, it's more like you are asking it to parse and split the string for you, which it can't do.

JavaScriptSerializer is pretty unforgiving and to be honest I always end up tearing my hair out when trying to deserialise an array like this...you are much better off defining a DTO class on the server side to handle the mapping:

 [Serializable]
 public class Titles
 {
    public List<Title> TheTitles { get; set; } 
 }

 [Serializable]
 public class Title
 {
    public string title { get; set; }
 }

So now your handler looks like this:

 public void ProcessRequest(HttpContext context)
        {
            try
            {
                context.Response.ContentType = "application/json";
                var data = context.Request;
                var sr = new StreamReader(data.InputStream);
                var stream = sr.ReadToEnd();    
                var javaScriptSerializer = new JavaScriptSerializer();
                var PostedData = javaScriptSerializer.Deserialize<Titles>(stream);    
                foreach (var item in PostedData.TheTitles )
                {
                   //this will write SteveJohnAndrew as expected in the response 
                   //(check the console!)
                   context.Response.Write(item.title);
                }
            }
            catch (Exception msg) { context.Response.Write(msg.Message); }
        }

And your AJAX is like this:

 function upload() 
        {
           //example data
            var Titles = [
                {'title':'Steve'}, {'title':'John'}, {'title':'Andrew'}
            ];    
            var myJSON = JSON.stringify({ TheTitles: Titles });    
            console.log(myJSON);    
            $.ajax({
                async: true,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                type: "POST",
                data: myJSON,
                url: "jsonhandler.ashx",
                success: function (msg) {
                    console.log(msg);
                }     
            });
        }

Note how the definition of the DTO classes matches exactly the definition of the JSON object properties, if it doesn't then the deserialisation will not work.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top