0

I have an ASP.NET / MVC4 application that uses jquery / ajax.

I'm trying to send a very large string from the client to the server using $.ajax( ... )

Primarily, we use the contentType "application/json" for this which works perfectly. In this one particular case however, the server throws an exception because the data being transmitted is too long. I've tried absolutely everything to increase the maxJsonLength for the deserializer in the web.config file but it doesn't work and no one can figure out why.

Someone suggested, as a work around, to send the contentType as "application/x-www-form-urlencoded; charset=UTF-8" and then have my controller manually deserialize the object rather than letting the MVC framework do it.

Javascript:

function AjaxRequest(data, dataType, type, url, contentType, success, error, args)
{
    if (url.indexOf("MyController/SomeMethodInMyController") > 0)
        contentType = "application/x-www-form-urlencoded; charset=UTF-8";

    data = JSON.stringify(data);

    $.ajax({async: args.async, cache: args.cache, data: data, dataType: dataType, type: type, url: url, contentType: contentType, traditional: true, headers : { ... }, beforeSend: { ... }, success: { ... }, error: { ... }, complete: { ...});
}

function SomeFunction()
{
    var object = {};
    object.Name = $("#someControl").val();
    object.RtfData = $("someOtherControl").val();

    AjaxRequest(object, 'html', 'post', 'MyController/SomeMethodInMyController', 'application/json;', function (response) { ... }, function (error) { ... });
}

In this case, my application no longer crashes "interally" where the MVC framework attempts to deserialize the object on its own. Now it bypasses all that and directly calls the method in my controller. Kind of hacky, but 3 days later I'll take what I can get.

C#:

public void SomeMethodInMyController(string formData)
{
    JavaScriptSerializer jss = new JavaScriptSerializer();
    jss.MaxJsonLenght = int.MaxValue;

    MyType objMyType = jss.Deserialize<MyType>(formData);

    //do stuff with objMyType
}

Problem is that when I set a breakpoint in this method, formData is null.

In my browser's console, before $.ajax(); is actually executed I typed typeof(data)into the console which returns "string". If I mouse over the symbol I can see all the data I expect it to contain is there. So why is that in my C# code the value is null?

sab669
  • 3,984
  • 8
  • 38
  • 75

1 Answers1

2

I think you need to send a FormData object and not just a string. Try changing your AjaxRequest function like this:

function AjaxRequest(data, dataType, type, url, contentType, success, error, args)
{
    if (url.indexOf("MyController/SomeMethodInMyController") > 0)
        contentType = "application/x-www-form-urlencoded; charset=UTF-8";

    var form = new FormData();
    form.append("MyData", JSON.stringify(data));


    $.ajax({processData: false, async: args.async, cache: args.cache, data: form, dataType: dataType, type: type, url: url, contentType: contentType, traditional: true, headers : { ... }, beforeSend: { ... }, success: { ... }, error: { ... }, complete: { ...});
}
Oggy
  • 1,516
  • 1
  • 16
  • 22
  • This results in a javascript exception "illegal execution". – sab669 Oct 13 '16 at 19:04
  • Do you mean 'illegal invocation'? I updated the answer to add "processData: false" to the ajax settings - can you see if you still get the exception with it? – Oggy Oct 13 '16 at 19:09
  • Ah, yes, my mistake. Looking at the error log now: `TypeError - Java Script Error : Illegal invocation: at document path 'localhost/myApp'. at AjaxRequest('[object Object]', 'html', 'post', '/MyController/SomeMethodInMyController', 'application/json;', 'function (response) { //if the response is not null we are showing the pop up to download the file. ` then just gives the rest of the stack trace. – sab669 Oct 13 '16 at 19:15
  • I just saw your edit; I'll try it now... takes about 10 minutes to test this bug so it'll be a little bit before I know... – sab669 Oct 13 '16 at 19:17
  • Try adding these two settings as well, just in case: contentType: false, mimeType: "multipart/form-data" – Oggy Oct 13 '16 at 19:18
  • No exception after adding `processData: false` but the value of `SomeMethodInMyController`'s parameter is still `null`. Same goes for setting the other 2 :( – sab669 Oct 13 '16 at 19:30
  • Right, here's an example of how to read multipart/form-data in the controller with ReadAsMultipart: http://stackoverflow.com/a/28370216/3605547 – Oggy Oct 13 '16 at 19:36
  • Accepting this as the solution; between passing it as a `FormData` object and then looking over the solutions in your linked question I was able to figure it out. In my controller, `Request.Form[0]` contains my JSON stringified data! Thank you so much for the help; I've been stuck on this all week. – sab669 Oct 14 '16 at 14:26