自定义操作结果返回MVC C#中的特定视图

时间:2014-10-21 14:04:54

标签: javascript ajax asp.net-mvc-4 c#-4.0

我有一个MVC应用程序,我试图让用户有机会下载文件的zip文件,但不成功。让我进一步解释。

在我的视图中( ImageViewer.cshtml )我有一个带有点击事件的div类,按下时我调用控制器方法( ImageViewerController.GetZipPhotos )处理下载zip文件。见下文:

div class="text" onclick="GetZipPhotos()">Download</div> 

和被调用的Javascript是这样的:

function GetZipPhotos() {   
        $.ajax({
                url: '@Url.Action("GetZipPhotos", "ImageViewer",Request.Url.Scheme)',
                type: 'POST',
                contentType: 'application/zip',
                error: function () {
                        alert('There was an error!'+result);
                        }
              });                     
    }

现在,在我的ImageViewerController中,我有以下方法:

[HttpPost]
    public ActionResult GetZipPhotos()
    {
        ZipResult newZipResult=new ZipResult(
            Server.MapPath("~/File1.txt"),
            Server.MapPath("~/File2.txt")
            );
        newZipResult.OutPutZipFileName = "PhotosZip.zip";
        return newZipResult;
    }

并且ZipResult自定义操作的声明是:

public class ZipResult:ActionResult
{
    private IEnumerable<string> _filesToZip;
    private string _outPutZipFileName="ZipFile.zip";        

    public ZipResult(params string[] filesToZip)
    {
        this._filesToZip = filesToZip;
    }        

    public override void ExecuteResult(ControllerContext context)
    {                                       
       using (ZipFile oneZipFile = new ZipFile()) {
           oneZipFile.AddFiles(_filesToZip);
           context.HttpContext.Response.ContentType = "application/zip";
           context.HttpContext.Response.AppendHeader("content-disposition", "attachment; filename=" + _outPutZipFileName);
           oneZipFile.Save(context.HttpContext.Response.OutputStream);
       }            
    }
}

问题是因为调用控制器的视图名称与实际方法(GetZipPhotos)不同,因此代码不起作用。视图的名称是ImageViewer.cshtml,控制器的名称是ImageViewerController。  正如我所理解的那样,MVC框架使用代码约定,因此它希望方法的名称与视图相同。问题是我的视图和方法是不同的,因此响应永远不会回到视图。  我想创建一个基本上没有任何内容的新视图,只是从方法中调用它并返回zip文件。如果这可能是一个可能的解决方案,我怎么能从动作结果告诉哪个视图发送响应吗

2 个答案:

答案 0 :(得分:1)

无需使用ajax进行文件下载。浏览器通常会开始下载并让您保持同一页面。此外,无需自定义操作结果,您只需使用FileResult即可。尝试这样的事情:

public FileResult GetZipPhotos()
{
    var filesToZip = new List<string> { Server.MapPath("~/File1.txt"), Server.MapPath("~/File2.txt") };

    var oneZipFile = new ZipFile();
    oneZipFile.AddFiles(filesToZip);

    return File(oneZipFile.ToByteArray(), "application/zip", "PhotosZip.zip");
}

当然,您需要弄清楚这部分oneZipFile.ToByteArray(),但ZipFile类可能已经有类似的东西。

答案 1 :(得分:1)

您的ajax调用正在将响应重定向到无处。

我会这样做:

使用隐藏的iframe,将其src更改为函数中所需的路径,它应该提示文件对话框。