[asp.net-mvc] MVC 컨트롤러에서 다운로드 할 파일을 표시하려면 어떻게해야합니까?

WebForms에서는 일반적으로 브라우저가 PDF와 같은 임의의 파일 유형과 파일 이름이있는 “파일 다운로드”팝업을 표시 할 수 있도록 다음과 같은 코드를 사용합니다.

Response.Clear()
Response.ClearHeaders()
''# Send the file to the output stream
Response.Buffer = True

Response.AddHeader("Content-Length", pdfData.Length.ToString())
Response.AddHeader("Content-Disposition", "attachment; filename= " & Server.HtmlEncode(filename))

''# Set the output stream to the correct content type (PDF).
Response.ContentType = "application/pdf"

''# Output the file
Response.BinaryWrite(pdfData)

''# Flushing the Response to display the serialized data
''# to the client browser.
Response.Flush()
Response.End()

ASP.NET MVC에서 동일한 작업을 어떻게 수행합니까?



답변

반품 FileResult또는 FileStreamResult파일이 존재하거나 즉석에서 그것을 만들 여부에 따라 액션에서.

public ActionResult GetPdf(string filename)
{
    return File(filename, "application/pdf", Server.UrlEncode(filename));
}


답변

브라우저의 PDF 플러그인에서 처리하는 대신 PDF 파일을 강제로 다운로드하려면 :

public ActionResult DownloadPDF()
{
    return File("~/Content/MyFile.pdf", "application/pdf", "MyRenamedFile.pdf");
}

브라우저가 기본 동작 (플러그인 또는 다운로드)으로 처리하도록하려면 두 개의 매개 변수를 보내면됩니다.

public ActionResult DownloadPDF()
{
    return File("~/Content/MyFile.pdf", "application/pdf");
}

브라우저 대화 상자에서 파일의 이름을 지정하려면 세 번째 매개 변수를 사용해야합니다.

업데이트 : Charlino가 맞습니다. 세 번째 매개 변수 (다운로드 파일 이름)를 전달할 때 Content-Disposition: attachment;Http 응답 헤더에 추가됩니다. 내 솔루션은 application\force-downloadmime-type 으로 전송 하는 것이었지만 다운로드 파일 이름에 문제가 발생하므로 좋은 파일 이름을 전송하려면 세 번째 매개 변수가 필요하므로 강제로 다운로드 할 필요가 없습니다 .


답변

Razor 또는 컨트롤러에서 동일한 작업을 수행 할 수 있습니다.

@{
    //do this on the top most of your View, immediately after `using` statement
    Response.ContentType = "application/pdf";
    Response.AddHeader("Content-Disposition", "attachment; filename=receipt.pdf");
}

또는 컨트롤러에서 ..

public ActionResult Receipt() {
    Response.ContentType = "application/pdf";
    Response.AddHeader("Content-Disposition", "attachment; filename=receipt.pdf");

    return View();
}

Chrome과 IE9에서 이것을 시도했는데 둘 다 pdf 파일을 다운로드하고 있습니다.

내 PDF를 생성하기 위해 RazorPDF 를 사용하고 있다고 추가해야합니다 . 여기에 대한 블로그가 있습니다. http://nyveldt.com/blog/post/Introducing-RazorPDF


답변

컨트롤러의 File 메서드를 봐야합니다. 이것이 바로 그 목적입니다. ActionResult 대신 FilePathResult를 반환합니다.


답변

mgnoonan,

이렇게하면 FileStream을 반환 할 수 있습니다.

/// <summary>
/// Creates a new Excel spreadsheet based on a template using the NPOI library.
/// The template is changed in memory and a copy of it is sent to
/// the user computer through a file stream.
/// </summary>
/// <returns>Excel report</returns>
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NPOICreate()
{
    try
    {
        // Opening the Excel template...
        FileStream fs =
            new FileStream(Server.MapPath(@"\Content\NPOITemplate.xls"), FileMode.Open, FileAccess.Read);

        // Getting the complete workbook...
        HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true);

        // Getting the worksheet by its name...
        HSSFSheet sheet = templateWorkbook.GetSheet("Sheet1");

        // Getting the row... 0 is the first row.
        HSSFRow dataRow = sheet.GetRow(4);

        // Setting the value 77 at row 5 column 1
        dataRow.GetCell(0).SetCellValue(77);

        // Forcing formula recalculation...
        sheet.ForceFormulaRecalculation = true;

        MemoryStream ms = new MemoryStream();

        // Writing the workbook content to the FileStream...
        templateWorkbook.Write(ms);

        TempData["Message"] = "Excel report created successfully!";

        // Sending the server processed data back to the user computer...
        return File(ms.ToArray(), "application/vnd.ms-excel", "NPOINewFile.xls");
    }
    catch(Exception ex)
    {
        TempData["Message"] = "Oops! Something went wrong.";

        return RedirectToAction("NPOI");
    }
}


답변

표준 작업 결과 FileContentResult 또는 FileStreamResult를 파일 다운로드에 사용할 수 있지만 재사용 성을 위해 사용자 지정 작업 결과를 만드는 것이 가장 좋은 솔루션 일 수 있습니다.

예를 들어 다운로드를 위해 즉시 Excel 파일로 데이터를 내보내는 사용자 지정 작업 결과를 만들어 보겠습니다.

ExcelResult 클래스는 추상 ActionResult 클래스를 상속하고 ExecuteResult 메서드를 재정의합니다.

IEnumerable 개체에서 DataTable을 생성하기 위해 FastMember 패키지를 사용하고 DataTable에서 Excel 파일을 생성하기 위해 ClosedXML 패키지를 사용하고 있습니다.

public class ExcelResult<T> : ActionResult
{
    private DataTable dataTable;
    private string fileName;

    public ExcelResult(IEnumerable<T> data, string filename, string[] columns)
    {
        this.dataTable = new DataTable();
        using (var reader = ObjectReader.Create(data, columns))
        {
            dataTable.Load(reader);
        }
        this.fileName = filename;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context != null)
        {
            var response = context.HttpContext.Response;
            response.Clear();
            response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            response.AddHeader("content-disposition", string.Format(@"attachment;filename=""{0}""", fileName));
            using (XLWorkbook wb = new XLWorkbook())
            {
                wb.Worksheets.Add(dataTable, "Sheet1");
                using (MemoryStream stream = new MemoryStream())
                {
                    wb.SaveAs(stream);
                    response.BinaryWrite(stream.ToArray());
                }
            }
        }
    }
}

컨트롤러에서 다음과 같이 사용자 지정 ExcelResult 작업 결과를 사용합니다.

[HttpGet]
public async Task<ExcelResult<MyViewModel>> ExportToExcel()
{
    var model = new Models.MyDataModel();
    var items = await model.GetItems();
    string[] columns = new string[] { "Column1", "Column2", "Column3" };
    string filename = "mydata.xlsx";
    return new ExcelResult<MyViewModel>(items, filename, columns);
}

HttpGet을 사용하여 파일을 다운로드하고 있으므로 모델없이 빈 레이아웃과 빈 뷰를 만듭니다.

즉석에서 생성 된 파일을 다운로드하기위한 사용자 지정 작업 결과에 대한 블로그 게시물 :

https://acanozturk.blogspot.com/2019/03/custom-actionresult-for-files-in-aspnet.html


답변

.ashx 파일 유형을 사용하고 동일한 코드를 사용하십시오.