发送我想要制作的文件并将其作为IHttpActionResult存储在内存中

问题描述 投票:0回答:2

我不确定我想做什么甚至是可能的。

我目前正在开发一个AngularJS Web应用程序,需要实现一种方法从我的数据库中获取数据,将其存储到List<object>中,将List<object>解析为.csv文件并将其加载到内存中,这样我就可以将其作为HttpResponseMessage

我已经拥有List<object>变量中的所有数据,并将使用CSVHelper将其解析为文件,但我在网上找到的所有示例都向我展示了如何使用File.WriteAllText()在本地导出文件,并且它们都使用File.OpenRead(filePath)在本地读取文件。

如何在内存中创建和存储文件并将其作为HttpResponseMessage发回?


编辑:

在挖掘之后,我能够想出这个,虽然它不起作用。当我运行代码时,我得到“无法访问此站点。来自Chrome的连接已休息.ERR_CONNECTION_RESET”。

希望这有助于可视化我正在尝试做的事情。

Javascript

me.downloadFile = function (fileId) {

    $http({
        method: 'POST',
        url: 'api/notices/CheckFileExists',
        params: { fileId: fileId }
    }).then(function success(result) {
        if (result.data === 'Y') {
            me.downloadOpen("POST", 'api/notices/DownloadFile?fileId=' + fileId, "", "");
        }
        else {
            $mdToast.show(
                $mdToast.simple()
                    .textContent(result.data)
                    .position("bottom right")
                    .hideDelay(2000)
            );
        }
    });
};

me.downloadOpen = function (verb, url, data, target) {
    var form = document.createElement("form");
    form.action = url;
    form.method = verb;
    form.target = target || "_self";

    if (data) {
        for (var key in data) {
            var input = document.createElement("input");
            input.name = key;
            input.value = typeof data[key] === "object" ? JSON.stringify(data[key]) : data[key];
            form.appendChild(input);
        }
    }

    form.style.display = 'none';
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);

C#

[HttpPost]
    public HttpResponseMessage DownloadFile(int fileId)
    {
        var user = GetUser();
        var fileContent = NoticesMethods.GetNoticeFile(fileId, user);

        using (Globals.WebAppsImpersonator())
        {
            if (fileContent.Count > 0)
            {
                using (var mem = new MemoryStream())
                using (var writer = new StreamWriter(mem))
                using (var csvWriter = new CsvWriter(writer))
                {
                    csvWriter.Configuration.Delimiter = ",";
                    csvWriter.WriteField("File ID");
                    csvWriter.WriteField("Account");
                    csvWriter.WriteField("Move Date");

                    foreach (var row in fileContent)
                    {
                        csvWriter.WriteField("\"" + row.FileId + "\"");
                        csvWriter.WriteField("\"" + row.Account + "\"");
                        csvWriter.WriteField("\"" + row.MoveDate + "\"");
                    }

                    writer.Flush();

                    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                    result.Content = new StreamContent(mem);
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
                    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    result.Content.Headers.ContentDisposition.FileName = "Notice.csv";

                    return result;
                }
            }
            return new HttpResponseMessage(HttpStatusCode.NotFound);
        }
    }
c# http export-to-csv
2个回答
1
投票

要创建一个csv文件并将其保存在内存中,您需要在CSVHelper代码之前实例化一个内存流。然后,您可以从控制器返回内存流字节数组作为base64字符串。

[HttpGet]
public IHttpActionResult Get(params)
{
    var result = "";
    using (var memoryStream = new MemoryStream())
    {
        using (var streamWriter = new StreamWriter(memoryStream))
        using (var csvWriter = new CsvWriter(streamWriter))
        {
            csvWriter.WriteRecords(listOfObjects);
        } 

        result = Convert.ToBase64String(memoryStream.ToArray()); 
    }

    return Ok(result);
}

在前端,您可能希望利用FileSaver.js库。它要求您首先将base64字符串转换为blob。这里有很多JS示例(Creating a Blob from a base64 string in JavaScript)。


0
投票

通过拼凑我在网上发现的一些东西,我找到了答案。任何人遇到类似的问题,这是我发现为我的案件工作的代码。 javascript是一样的,但我对C#做了一些小改动。

而不是发送回StreamContent我发送回StringContent。这样我需要做的就是将我的数据写入CSV文件,然后将其读入字符串。

这是代码:

[HttpPost]
    public HttpResponseMessage DownloadFile(int fileId)
    {
        var user = GetUser();
        var fileContent = NoticesMethods.GetNoticeFile(fileId, user);


        using (Globals.WebAppsImpersonator())
        {
            if (fileContent.Count > 0)
            {
                using (var mem = new MemoryStream())
                using (var reader = new StreamReader(mem))
                using (var writer = new StreamWriter(mem))
                using (var csvWriter = new CsvWriter(writer))
                {
                    csvWriter.Configuration.Delimiter = ",";
                    csvWriter.WriteField("File ID");
                    csvWriter.WriteField("Account");
                    csvWriter.WriteField("Move Date");
                    csvWriter.NextRecord();

                    foreach (var row in fileContent)
                    {
                        csvWriter.WriteField("\"" + row.FileId + "\"");
                        csvWriter.WriteField("\"" + row.Account + "\"");
                        csvWriter.WriteField("\"" + row.MoveDate + "\"");
                        csvWriter.NextRecord();
                    }

                    writer.Flush();
                    mem.Position = 0;

                    var file = reader.ReadToEnd();

                    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                    result.Content = new StringContent(file);
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
                    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    result.Content.Headers.ContentDisposition.FileName = "Notice.csv";

                    return result;
                }
            }
            return new HttpResponseMessage(HttpStatusCode.NotFound);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.