Как передать файл DOCX из контроллера в View с помощью AJAX? - PullRequest
1 голос
/ 30 октября 2019

Привет, сообщество Stack Overflow, первое сообщение, твори свою магию!

Проблема, с которой я столкнулся, заключается в том, что я могу сгенерировать свой docx файл, но когда я пытаюсь вернутьсяэто данные возвращаются в формате, который я никогда не видел раньше? Кто-нибудь знает, что это такое?

Снимок экрана неопознаваемого кода - похоже на Wingdings

Начиная с вида бритвы

 //Start action
$('#returnDeductionSheets').click(function () {

    //Retrieve date options for user to select
    $.ajax({
        async: true,
        type: 'POST',
        url: 'ReturnDeductionsSheetList',
        success: function (data) {

            if (data != null) {
                var options = data;

                //Format JSON dates into read-able date time format
                function formatDate(options) {
                    var dateString = options.substring(6);
                    var currentTime = new Date(parseInt(dateString));
                    var month = currentTime.getMonth() + 1;
                    var day = currentTime.getDate();
                    var year = currentTime.getFullYear();
                    var date = day + "/" + month + "/" + year;
                    return date;
                };

                //Check if I have more than one date, then return the options via a Bootbox view
                if (options.length > 1) {
                    bootbox.prompt({
                        title: "Select the Deductions Sheet you would like to print.",
                        inputType: 'checkbox',
                        inputOptions: [
                            {
                                text: 'Deductions commenced on ' + formatDate(options[3]),
                                value: options[2],
                            },
                            {
                                text: 'Deductions commenced on ' + formatDate(options[1]),
                                value: options[0],
                            }
                        ],
                        callback: function (result) {
                            //Pass the selected option into another AJAX method to generate the document else return to the view
                            if (result != null) {

                                $.ajax({
                                    type: 'POST',
                                    url: '@Url.Action("DeductionsSheet", "Home")?result=' + result,
                                    contentType: 'application/json; charset=utf-8',
                                    success: function (data) {
                                        if (data.fileName != "") {
                                            //window.location = "@Url.RouteUrl(new { Controller = "Home", Action = "Download" })/?file=" + data.fileName;
                                            window.location = '/Home/ContractSpecificDocuments?file=' + data.fileName;
                                        }
                                    }
                                });
                            } else {
                                return;
                            };
                        }
                    });

                }
                else {

Я рад, что код Bootbox работает и значение, которое передается в DeductionsSheet ActionResult в контроллере, поэтому я перейду к этому коду.

DeductionsSheetметод (начало метода) Значение входит в метод как массив, который я получаю через индекс [0].

public ActionResult DeductionsSheet(List<object> result)
{
    //BOILER PLATE CODE
    /////////////////////////////////////////
    XceedDeploymentLicense.SetLicense();

    var dateStamp = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss");

    _replacePatterns = new Dictionary<string, string>();

    int contractNumber = Convert.ToInt32(Request.Cookies["ContractNumber"].Value);
    int contractContibutionHistoryId = Convert.ToInt32(result[0]);

Документ сгенерирован Метод DeductionsSheet (нижняя часть метода)

document.SaveAs(DocumentOutputDirectory + @"\RMContributions_" + dateStamp + @".docx");
}

string fileName = "RMContributions_" + dateStamp + @".docx";
return File(new FileStream(DocumentOutputDirectory + @"\RMContributions_" + dateStamp + @".docx", FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName);

ActionResult завершается и возвращается к методу AJAX, показанному ниже здесь (тот же код, что и в блоке Razor View выше).

success: function (data) {
    if (data.fileName != "") {
        //window.location = "@Url.RouteUrl(new { Controller = "Home", Action = "Download" })/?file=" + data.fileName;
        window.location = '/Home/ContractSpecificDocuments?file=' + data.fileName;
    }
}

Я не уверен, что это проблема разбора типа данных или если что-то нужно сериализовать, я открыт для всех предложений.

Теперь я не привержен этому подходу, поэтому, если кто-то может предложить альтернативу, пока она работает, я счастлив. В идеале я бы вызвал метод AJAX и передал данные в контроллер, а затем не вернулся бы к методу AJAX, но я не нашел способа сделать это.

Я попробовал более простую альтернативу, при которой в обратном вызове Bootbox я запускаю ActionResult DeductionsSheet, используя событие триггера jQuery, но при таком подходе я не смог передать данные в контроллер.

Альтернативный подход с использованием события триггера

callback: function (result) {
    //Pass the selected option into another AJAX method to generate the document else return to the view
    if (result != null) {

        $('#deductionsSheet').trigger('click', [result]);

    } else {
        return;
    };
}

Спасибо за вашу помощь.

...