简体   繁体   English

从JavaScript打开JSON文件

[英]Opening a JSON file from javascript

I have a C# functoin in my MVC application that returns a JSON representation of a csv file. 我的MVC应用程序中有一个C#函数,它返回一个csv文件的JSON表示形式。 I am trying to catch that in javascript and open the file. 我试图在javascript中捕获该错误并打开文件。 Basically I want the browser do its thing and let the user decide if he want to open it, save it or cancel. 基本上,我希望浏览器执行其操作,然后让用户决定是否要打开,保存或取消。 I am unable to get that popup to ask me to open the file. 我无法看到该弹出窗口要求我打开文件。 Below are the functions 以下是功能

C# Function C#功能

[HttpPost]
public ActionResult ExportToCsv(string fileContents, string fileName)
{
    fileContents = fileContents.Replace("-CARRIAGE-", "\r\n");
    return Json(new { url = File(Encoding.UTF8.GetBytes(fileContents), "text/csv", fileName) }); ;
}

This is the javascript where I am making the ajax call to the function 这是我正在对该函数进行ajax调用的javascript

$("#btnExport").click(function (event) {
    event.preventDefault();
    var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
    $.ajax({
        url: "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.csv",
        type: 'Post',
        success: function (result) {
            window.open(result.url);
        }
    });
});

I know I am missing something. 我知道我缺少什么。 Can someone please help. 有人可以帮忙吗?

EDIT 编辑

After reading through all the potential answers and comments, this is what I am trying to achieve. 阅读完所有可能的答案和评论后,这就是我要实现的目标。 So if my code is all horribly wrong please let me know. 因此,如果我的代码完全错误,请通知我。

I have a grid and I have an export to excel button. 我有一个网格,并且我有一个导出到excel按钮。 I have a method that converts the data i want into comma delimited text in javascript itself. 我有一种方法可以将我想要的数据转换成JavaScript本身中的逗号分隔文本。 I need to present this to the user as a downloadable csv file. 我需要将其作为可下载的csv文件呈现给用户。 For this I was creating the File object using the controller method. 为此,我使用控制器方法创建File对象。 The previous incarnation was a Get method and I faced limitations due to querystring length restrictions. 先前的版本是Get方法,由于查询字符串长度的限制,我遇到了一些限制。 So I tried converting it to a POST method and it is not working. 因此,我尝试将其转换为POST方法,但无法正常工作。

This is the previous version of the code that works for smaller amounts of data 这是该代码的先前版本,可处理少量数据

Javascript Java脚本

   $("#btnExport").click(function (event) {
            event.preventDefault();
            var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
            window.location.href = "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.csv";
        });

C# Function C#功能

    [HttpGet]
    public ActionResult ExportToCsv(string fileContents, string fileName)
    {
        fileContents = fileContents.Replace("-CARRIAGE-", "\r\n");
        return File(Encoding.UTF8.GetBytes(fileContents), "text/csv", fileName);
    }

Hope this now gives you all more context. 希望现在能给您更多的背景信息。 Basically I needed to convert my GET method to a POST method and use it from Javascript. 基本上,我需要将GET方法转换为POST方法并从Javascript使用它。

You can't save binary files using ajax - it's restricted due to security reasons. 您无法使用Ajax保存二进制文件-由于安全原因,它受到限制。 If you'd like the user to save the file - return a binary stream from your controller as you post the data back in JSON format (ie if the user wants to save it). 如果您希望用户保存文件,则在以JSON格式发布数据时,即从控制器返回二进制流(即,用户是否要保存数据)。

I've done a similar thing here: How to properly create and download a dynamically generated binary *.xlsx file on .net MVC4? 我在这里做了类似的事情: 如何在.net MVC4上正确创建和下载动态生成的二进制* .xlsx文件?

Maybe save it as a json file instead and load in the current page's DOM. 也许将其另存为json文件,然后加载到当前页面的DOM中。 Although I though I am confused, don't you just have a JSON response containing a URL to your CSV file is which is just that a CSV file, not a JSON representation of CSV? 尽管我感到困惑,但是您是否只是拥有一个包含CSV文件URL的JSON响应,这仅仅是一个CSV文件,而不是CSV的JSON表示形式?

$("#btnExport").click(function (event) {
        event.preventDefault();
        var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
        $.ajax({
            url: "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.json",
            type: 'Post',
            success: function (result) {
                var myDummyElement = $('<div>'); //dummy div so you can call load
                myDummyElement .load('result.url #myJson');
            }
        });
    });

<div id="myJson"></div>

[HttpPost]
    public ActionResult ExportToCsv(string fileContents, string fileName)
    {
        //change fileName to be a .json extension
        fileContents = fileContents.Replace("-CARRIAGE-", "\r\n");
        return Json(new { url = File(Encoding.UTF8.GetBytes(fileContents), "text/csv", fileName) }); ;
    }

If you use ajax , you're expected to handle the result in code. 如果使用ajaxajax在代码中处理结果。 But you can't trigger a file download (directly) that way. 但是您不能以这种方式(直接)触发文件下载。

Instead, create a (hidden) form and post it to a (hidden) iframe (by giving the iframe a name and specifying that as the target of the form ), making sure that the response specifies the header Content-Disposition: attachment . 而是创建一个(隐藏的) form并将其发布到(隐藏的) iframe (通过给iframe一个name并将其指定为formtarget ),确保响应指定了标头Content-Disposition: attachment That will trigger the browser to offer to save the file. 这将触发浏览器提供保存文件的功能。 Optionally in the header you can suggest a filename for the file by adding ; filename="fname.ext" (可选)在标题中,您可以通过添加来建议文件的文件名; filename="fname.ext" ; filename="fname.ext" to the header value. ; filename="fname.ext"到标题值。 Eg Content-Disposition: attachment; filename="fname.ext" 例如Content-Disposition: attachment; filename="fname.ext" Content-Disposition: attachment; filename="fname.ext" . Content-Disposition: attachment; filename="fname.ext"

The client-side looks something like this: 客户端看起来像这样:

$("#btnExport").click(function (event) {
    event.preventDefault();
    var csv = table2csv(noteTypeTable, "full", "Table.dataTable", "noteTypes");
    var frame = $('iframe[name="formreceiver"]');
    if (!frame.length) {
        frame = $('<iframe name="formreceiver"></iframe>').appendTo(document.body).css("display", "none");
    }
    var form = $("#senderform");
    if (!form.length) {
        form = $('<form id="senderform"></form>').appendTo(document.body);
    }
    form = form[0]; // Raw DOM element rather than jQuery wrapper
    form.target = "formreceiver";
    form.action = "/Admin/Admin/ExportToCsv/?fileContents=" + csv + "&fileName=NoteTypes.csv";
    form.method = "POST";
    form.submit();
});

The server side is just a standard form response with the Content-Disposition header. 服务器端只是带有Content-Disposition标头的标准表单响应。

I've used this technique for years, with browsers from IE6 onward. 从IE6开始,我已经使用这种技术很多年了。 My usual setup already has the iframe in the markup (rather than creating it as above), but other than that this is basically what I do. 我通常的设置已经在标记中包含了iframe (而不是像上面那样创建),但是除此之外,这基本上是我要做的。

Note that it's important you're doing this in response to a button click by the user. 请注意,执行此操作以响应用户单击按钮很重要。 If you weren't, there would be popup-blocker issues. 如果不是这样,将会出现弹出窗口阻止程序问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM