1

I want to send a large amount of cached json data from an import process to an MVC controller which will in turn respond with a text file in CSV format.

The problem is if I use an AJAX call, there is no way for the browser to handle the response and download the file.

If I use a regular form post, then the browser would handle the returned file response. However, AFAIK to post a form I can't send Json data and I don't want to send the data on the query string.

Seems like I'm between a rock and a hard place. What are my best options for achieving this? I want to avoid writing data files to the server. Basically I just want to send lots of json data and return as a download request to the browser.

jaffa
  • 26,770
  • 50
  • 178
  • 289

4 Answers4

1

Just my two cents. If you don't want to create a file, just cache data in session (or wherever you like).

So:

  1. perform ajax post of json data
  2. in the Controller Action store the data somewhere (e.g. Session) and create a key to access it later (a guid) and return it as a json object.
  3. in the success ajax function, invoke another action passing the key obtained via normal location.href = url + key

It's pretty the same of saving a file server side, except there's no file.

BigMike
  • 6,683
  • 1
  • 23
  • 24
  • +1 BigMike. should work in most cases, tho of course browser 'quirks' may have to be accounted for – jim tollan Jan 05 '12 at 11:11
  • This sounds promising. I'm just concerned about the amount of data to cache in the session. There could be 100s-1000s of strings, as I'm not sure how big these imports could be. Each string won't be particular long though. – jaffa Jan 05 '12 at 11:13
  • jaffa - you could of course save it to the filesystem, rather than to session and then delete the file on successful download. – jim tollan Jan 05 '12 at 11:15
  • 1
    @Jim - a bulb has just lit. What about if I just populate a db table with the rows I want to cache after the import, and just serve these when the user requests the download? – jaffa Jan 05 '12 at 11:20
  • @jaffa that will probably a better approach. Caching on db then provide some way to retrieve datas. Should work pretty good. – BigMike Jan 05 '12 at 11:36
  • 1
    @jaffa - yes, a table based approach would work well. you could also add a datetime column onto that same table to indicate that the 'file' had been requested and downloaded, then that could serve as an archive feature. you could of course extend this scheme to incorporate download rights etc on the data. – jim tollan Jan 05 '12 at 11:46
0

jaffa,

you may gain inspiration from this post on SO:

How to post an array of complex objects with JSON, jQuery to ASP.NET MVC Controller?

in practice, I post json objects via ajax as a matter of course in the admin sections of my apps. as for sending back a csv output, this would be difficult (if not impossible) to do via the partialupdate (i.e. to invoke the save dialog). you could of course return the csv as a partial and populate a div, but I guess this wouldn't really be an acceptable solution.

Community
  • 1
  • 1
jim tollan
  • 22,305
  • 4
  • 49
  • 63
0

I think I would assign the JSON data to an <input type='hidden'/> and then do a $('form').submit().

amiuhle
  • 2,673
  • 1
  • 19
  • 28
  • Interesting approach, I think I'd have to join all the separate rows with a CR delimeter. Not sure how much data this field could contain though... – jaffa Jan 05 '12 at 11:49
  • I posted another, probably better solution. If you want to go with the forms based approach, I think the [HTML5 File APIs](http://www.html5rocks.com/en/tutorials/file/filesystem-sync/) would be worth looking into. That's not yet supported on all browsers though. – amiuhle Jan 05 '12 at 12:29
0

Actually, I think the best solution is the following:

  1. Do an AJAX POST which fetches the CSV from the server
  2. Use the data: URI scheme to view the CSV:

Either directly

location.href = "data:text/csv;charset=utf-8,Value 1, Value 2, Value 3";

or prepare a link when the AJAX finishes, something like this:

<a href="data:text/csv;charset=utf-8,Value 1, Value 2, Value 3">Conversion finished. Save</a>

This works with limitations in IE8. Full support in IE9 and, of course, everywhere else.

amiuhle
  • 2,673
  • 1
  • 19
  • 28