2

My MVC3 app uploads documents from the user to our server. I am returning a JsonResult to display any errors, if any:

  [HttpPost] 
    public JsonResult SaveDocument(DocumentModel model, HttpPostedFileBase postedFile)
    {
         //my wonderful code
         return Json(new { success = true, message="ok" });

     }

Heres how i submit the request:

 var isSubmitting = false;
  var addDocumentOptions = {
       beforeSubmit: beforeAddDocumentSubmit,  // pre-submit callback 
      success: afterDocumentSubmit  // post-submit callback 
  };
  $('#btnCreateDocument').click(function (e) {
      e.preventDefault();
      $('#divError').html('');
      if (!isSubmitting) {
          $('#createDocForm').submit();
      }
    });

This javascript function runs when the upload is complete:

    function afterDocumentSubmit(responseText, statusText, xhr, $form) {
        if (responseText.success) {
            //no errors
          } else {
             $('#divError').html('Error: ' + responseText.message);
     }
   }

In FF, Chrome etc., my javascript code runs fine, but in IE, the browser wants to download the Json result as text. I get a download/open file dialog box that shouldnt appear. How do i make IE not download my Json result and behave like the other browsers? Thanks

BoundForGlory
  • 4,114
  • 15
  • 54
  • 81
  • Can you post the code that actually handles the submit and starts the Ajax request? And, if you're submitting a form with Ajax, are you [preventing the default action](http://api.jquery.com/event.preventDefault/) for its [`submit` event](http://api.jquery.com/submit/)? – Jonathan Lonowski Jun 29 '12 at 17:28
  • 1
    Duplicate? http://stackoverflow.com/questions/8591998/ie-tries-to-download-json-in-asp-net-mvc-3 – Derek 朕會功夫 Jun 29 '12 at 17:28

3 Answers3

9

I ran into a similar problem doing the same in Spring MVC on Java. The problem was that Spring was returning the content-type of the JSON result as application/json, which seems to make IE want to download it. You can try changing the content-type to text/plain; IE won't prompt you to download the file in this case. I suspect that something similar might be happening here.

You could try:

return Json(new { success = true, message = "ok" }, "text/plain");

In response to your new problem: the issue is that responseText is just a string. What you need to do is to convert it into a Javascript Object. You can do it like this:

var response = JSON.parse(responseText);
if(response.success) {
   ...
}

Most browsers support JSON.parse(). If you're having issues with non-compliant browsers, you can always use the JSON Javascript Library.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • I spoke too soon...Now my Json response is returning false, even though its being set to true. So my div is being loaded, but the responseText.message is 'undefined' – BoundForGlory Jun 29 '12 at 17:42
  • That's because `responseText` is just text. You'll need to convert it to JSON. Editing my answer. – Vivin Paliath Jun 29 '12 at 17:52
  • This may sound crazy, but im doing this in another area of my app. The only difference is, im uploading a file with an added paramerter of type HttpPostedFileBase. The one that works doesnt have the extra parameter – BoundForGlory Jun 29 '12 at 18:01
  • Interesting. I'm not too familiar with C# and ASP.NET MVC so I'm not sure of the implications of using `HttpPostedFileBase`. Did you try it with the changes I suggested? – Vivin Paliath Jun 29 '12 at 18:02
  • I did...the app just sat there. So i didnt know what it was doing....plus the json.js file is 19k in size – BoundForGlory Jun 29 '12 at 18:10
  • You could try logging the resposeText to make sure that the client side code is actually seeing it. – Vivin Paliath Jun 29 '12 at 18:32
  • Setting the response type to text/plain didn't work for me. Using the following worked: [HttpPost] public JsonResult Add() { var result = /* your result generation code here */; return new JsonResult() { Data = result, ContentType = "text/json" }; } – Auri Rahimzadeh Jul 03 '13 at 20:14
2

Wild guess: you are using the jquery.form plugin which enables you to upload files using AJAX and you haven't read the documentation which states the following:

Browsers that support the XMLHttpRequest Level 2 will be able to upload files seamlessly and even get progress updates as the upload proceeds. For older browsers, a fallback technology is used which involves iframes since it is not possible to upload files using the level 1 implmenentation of the XMLHttpRequest object. This is a common fallback technique, but it has inherent limitations. The iframe element is used as the target of the form's submit operation which means that the server response is written to the iframe. This is fine if the response type is HTML or XML, but doesn't work as well if the response type is script or JSON, both of which often contain characters that need to be repesented using entity references when found in HTML markup.

To account for the challenges of script and JSON responses when using the iframe mode, the Form Plugin allows these responses to be embedded in a textarea element and it is recommended that you do so for these response types when used in conjuction with file uploads and older browsers. Please note, however, that if there is no file input in the form then the request uses normal XHR to submit the form (not an iframe). This puts the burden on your server code to know when to use a textarea and when not to.

Now that you have read it you should take the respective actions if you want your code to work under IE as I have exemplified in this post.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
1

The proper JsonResult return should look like so:

[HttpPost] 
public JsonResult SaveDocument(DocumentModel model, HttpPostedFileBase postedFile)
{
    ...
    return Json(new { success = true, message="ok" }, "application/json; charset=utf-8", JsonRequestBehavior.AllowGet);
}
CD Smith
  • 6,597
  • 7
  • 40
  • 66
  • I tried this, but now my Json response is returning false, even though its being set to true. So my div is being loaded, but the responseText.message is 'undefined' – BoundForGlory Jun 29 '12 at 17:43
  • See Darin's answer about trying to upload via Ajax. If you aren't using the plugin, then you cannot upload via Ajax. Plus, I suggest you get super friendly with Chrome Dev tools, Fiddler and Firebug – CD Smith Jun 29 '12 at 18:12
  • this will really enforce json as an application, and therefore IE will download this rather than apply/return it as text. – AceMark Oct 18 '13 at 00:32