1

So I have an interesting question. I have a form where a user draws an image on a canvas (think a signature pad). I then need to send the image to my C# Controller (I am using ASP.NET MVC 5). The code I have functions for shorter strings, but when I try to pass the PNG data, it is too long and I recieve a HTTP Error 414. The request URL is too long error. Here is my code:


Html:

<form id="mainForm" action="submitUserAnswer" method="post">
    <input type="hidden" id="userOutput" name="output" value="" />
    //...other form elements, signature box, etc.
</form>

Javascript:

function goToNextQuestion() {
    var output = $('#signature').jSignature("getData");
        $('#userOutput').val(output);
        $('#mainForm').submit();
}

C#:

public ActionResult submitUserAnswer()
    {
        //use the userOutput for whatever
        //submit string to the database, do trigger stuff, whatever
        //go to next question
        System.Collections.Specialized.NameValueCollection nvc = Request.Form;
        string userOutput = nvc["output"];
        ViewBag.Question = userOutput;
        return RedirectToAction("redirectToIndex", new { input = userOutput });
    }

    public ActionResult redirectToIndex(String input)
    {

        ViewBag.Answer = input;
        return View("Index");
    }

My png data is very long, so the error makes sense. My question is how can I get the png data back to my controller?

perennial_
  • 1,798
  • 2
  • 26
  • 41
  • You are going to have to find another means of sending the data (separate from the Url) IE has an internal hard limit on Url length of 1042 characters, as I suspect does IIS. – Kevin Jul 23 '15 at 15:58
  • There can be multiple reasons for this. 1) IIS may have a limit on the maximum data you can transfer using POST request.Check the settings. 2)You need to encode the file in a certain format. So you can recover the image on the server side. – Untimely Answers Jul 23 '15 at 16:11
  • How would I go about encoding the file in a format? – perennial_ Jul 23 '15 at 17:32

2 Answers2

0

Maybe you just need to increase allowed GET request URL length.

If that doesn't works I have an aspx WebForm that saves a signature, and I use a WebMethod

[ScriptMethod, WebMethod]
public static string saveSignature(string data)
{
    /*..Code..*/
}

and I call it like this:

PageMethods.saveSignature(document.getElementById('canvas').toDataURL(), onSucess, onError);

also I have to increase the length of the JSON request and it works fine, with no problems with the lenght.

In MVC there isn't WebMethods, but JSON and AJAX requests do the job, just save the data in a session variable, and then use it when need it.

Hope it helps

Community
  • 1
  • 1
Enrique Zavaleta
  • 2,098
  • 3
  • 21
  • 29
0

You have error because your data is string (base64) and have max limit for send characters, better way is to create blob (png file) from base64 at client side, and send it to server. Edit. All listed code here, exists in stackoverflow posts.

function dataURItoBlob(dataURI) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
    var byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    var blob = null;
    // TypeError old chrome and FF
    window.BlobBuilder = window.BlobBuilder || 
                         window.WebKitBlobBuilder || 
                         window.MozBlobBuilder || 
                         window.MSBlobBuilder;
    if(window.BlobBuilder){
         var bb = new BlobBuilder();
         bb.append(ab);
         blob = bb.getBlob(mimeString);
    }else{
         blob = new Blob([ab], {type : mimeString});
    }
    return blob;
}

function sendFileToServer(file, url, onFileSendComplete){
   var formData = new FormData()
   formData.append("file",file); 
   var xhr = new XMLHttpRequest();
   xhr.open('POST', url, true);
   xhr.onload = onFileSendComplete;
   xhr.send(formData);
}

var base64 = $('#signature').jSignature("getData");
var blob = dataURItoBlob(base64);
var onComplete = function(){alert("file loaded to server");}
sendFileToServer(blob, "/server", onComplete)
Alex Nikulin
  • 8,194
  • 4
  • 35
  • 37