【问题标题】:Custom action result return specific view in MVC C#自定义操作结果返回 MVC C# 中的特定视图
【发布时间】:2014-10-21 14:04:54
【问题描述】:

我有一个 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 文件。如果这可能是一个可能的解决方案,我如何从操作结果中判断要发送哪个视图回应?

【问题讨论】:

  • 你怎么知道这不起作用?我没有看到您对 ajax 调用的结果(zip 文件)做任何事情。顺便说一句,您不需要将其设为 ajax 调用。指向ImageViewer/GetZipPhotos 的简单链接应该可以满足您的需求。此外,您可能希望使用内置的 FileResult 并在该操作中制作 zip 文件。
  • 1) 这里不涉及视图。您正在返回一个完全形成的结果。 2) 你不能只通过 AJAX 请求一个 zip 文件。您也许可以使用 HTML5 File API 从 AJAX 调用中读取返回的数据以在本地创建文件,然后提示用户下载该文件。但是,您必须处理所有这些;浏览器默认不会。 3)正如@Floremin 所说,无论如何都没有理由使用AJAX。只需直接链接到此操作即可。
  • 我尝试实施以下文章中的解决方案:campusmvp.net/blog/… Floremin 我将尝试您的提示。克里斯,你建议的解决方案虽然肯定可以工作,但此刻似乎有点令人生畏。

标签: javascript ajax asp.net-mvc-4 c#-4.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 类可能已经有类似的东西了。

【讨论】:

  • Floremin ajax 调用是我的问题的根源。我切换到@Html.ActionLink 并且它有效。我不需要更改任何其他内容,只需这个。
【解决方案2】:

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

我会这样做:

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

【讨论】:

  • Andreas 它是导致问题的 ajax 调用。
  • @SotirisZegiannis 是的。因此建议使用 iframe。大多数(如果不是全部)ajax 下载器组件,你会发现在线也可以使用 iframe :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多