How to download a file through ajax request in asp.net MVC 4

I think there is no need of Ajax call you can do simply using hyperlink as below example.

View Code

<a href="@Url.Action("DownloadAttachment", "PostDetail", new { studentId = 123 })">Download Form</a>

Controller Method

public ActionResult DownloadAttachment(int studentId)
{          
    // Find user by passed id
    var file = db.EmailAttachmentReceived.FirstOrDefault(x => x.LisaId == studentId);    
    byte[] fileBytes = System.IO.File.ReadAllBytes(file.Filepath);    
    return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, file.Filename);                           
}

The following code will help you to create the pdf/excel file in server and allow to download in browser through ajax call.

Controller for creating the pdf/excel file

public async Task<JsonResult> CardStatusReportExport(ReportFilterInputModel cardStatusReportInputModel, string type, string sortOrder)
    {
        cardStatusReportInputModel.ReportType = Reprot_Type_Const.CardStatus;
        cardStatusReportInputModel.ReportFormat = type;

        var CardStatusReport = await _reportDocGeneration.DocGeneartion(cardStatusReportInputModel);
        string result = Path.GetTempPath();
        string fileName = "CardStatusReport" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
        if (type.Equals(Constants.FILE_TYPE_PDF))
        {
            fileName = fileName + Constants.FILE_EXTENSION_PDF;
            System.IO.File.WriteAllBytes(result + fileName, CardStatusReport);
        }
        else
        {
            fileName = fileName + Constants.FILE_EXTENSION_EXCEL;
            System.IO.File.WriteAllBytes(result + fileName, CardStatusReport);
        }
        return Json(new { fileName = fileName});
    }

The following controller code will allow to download the created file from a single ajax call

[HttpGet]    
    public async Task<ActionResult> Download(string file)
    {
        var path = Path.Combine(Path.GetTempPath(),file);
        var memory = new MemoryStream();
        try
        {
            using (var stream = new FileStream(path, FileMode.Open))
            {
                await stream.CopyToAsync(memory);
            }
        }
        catch (Exception e)
        {
            ModelState.AddModelError("FileNotFoundError", e.Message);
            return Content(e.Message);
        }
        memory.Position = 0;
        return File(memory, GetContentType(path), Path.GetFileName(path));
    }

    private string GetContentType(string path)
    {
        var types = MediaType.GetMimeTypes();
        var ext = Path.GetExtension(path).ToLowerInvariant();
        return types[ext];
    }

Use the below ajax call for creation of pdf/excel file and download the same.

$.ajax({
                method: 'POST',
                data: { type: val, cardStatusReportInputModel: payload, sortOrder : sortOrder},
                url: '@Url.Action("CardStatusReportExport", "Reports")'
            }).done(function (data, statusText, xhdr) {
                try {
                    if (data.fileName != "") {
                        window.location.href = "@Url.RouteUrl(new { Controller = "Reports", Action = "Download"})/?file=" + data.fileName;
                        ShowMessageAlert('@Html.Raw(Localizer["Report has been exported successfully"].Value.ToString())');
                    }
                    $("#divLoader").hide();
                }
                catch (e) {
                    $("#divLoader").hide();
                }
            }).fail(function (xhdr, statusText, errorText) {
                alert('error');
                $("#divLoader").hide();
            });

Please, try this in ajax success

success: function () {
    window.location = '@Url.Action("DownloadAttachment", "PostDetail")';
}

Updated answer:

public ActionResult DownloadAttachment(int studentId)
{          
    // Find user by passed id
    // Student student = db.Students.FirstOrDefault(s => s.Id == studentId);

    var file = db.EmailAttachmentReceived.FirstOrDefault(x => x.LisaId == studentId);

    byte[] fileBytes = System.IO.File.ReadAllBytes(file.Filepath);

    return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, file.Filename);                       

}

Ajax request:

$(function () {
        $("#DownloadAttachment").click(function () {
            $.ajax(
            {
                url: '@Url.Action("DownloadAttachment", "PostDetail")',
                contentType: 'application/json; charset=utf-8',
                datatype: 'json',
                data: {
                    studentId: 123
                },
                type: "GET",
                success: function () {
                    window.location = '@Url.Action("DownloadAttachment", "PostDetail", new { studentId = 123 })';
                }
            });

        });
    });