10

我的 ASP.NET-MVC 项目中有以下 JavaScript 代码和控制器操作:

Javascript:

$("#exportPPT").live('click', function (e) {
    window.location.href = "/Initiative/GenerateFile" + GenerateParams();
});

C#控制器:

    public ActionResult GenerateFile(MyParams myParams)
    {
        var template = Server.MapPath(PPT_ROOT + "/template.pptx");
        IEnumerable<Order> orders = Model.GetOrders(myparams);
        var pptResults = GeneratePowerpointFile(orders);
        return File(pptResults.Content, "application/vnd.ms-powerpoint", pptResults.FileName);
    }

但在某些条件下,让我们说什么orders.Count()时候0不是生成文件,我宁愿向用户返回一条错误消息,说你有一个错误。

鉴于上面的代码,实现这一目标的最佳方法是什么?我想将其更改为 AJAX 调用,但我不确定如何下载我的Fie()并将其打包到 JSON 请求中(或者是否支持)。

4

7 回答 7

11

我会向另一个检查订单计数的控制器操作发起 $.get 请求。返回该值,并在适当时返回错误消息。在需要时显示错误消息,否则处理您的重定向以下载您的文件。这是对控制器的额外调用,但它允许您完全控制并处理出现错误的可能性,而无需重定向用户。

$("#exportPPT").live('click', function (e) {
  $.get( "/Initiative/CheckForOrders" + GenerateParams(), function( data ) {
    if (data.IsValid) {
      window.location.href = "/Initiative/GenerateFile" + GenerateParams();
    } else {
      alert(data.ErrorMessage); // or show a div containing error message
    }
  });
});

控制器动作:

public ActionResult CheckForOrders(MyParams myParams)
{
  IEnumerable<Order> orders = Model.GetOrders(myparams);
  if (orders.Any())
    return Json(new { IsValid=true }, JsonRequestBehavior.AllowGet);

  return Json(new { IsValid=false, ErrorMessage="No orders" }, JsonRequestBehavior.AllowGet);
}
于 2014-01-14T14:14:11.583 回答
5

我会返回一个表示资源不存在的状态并返回 null?然后,您可以在您的 javascript 中相应地处理它,而不必担心执行多个 ajax 调用来检查一个是否可用,或者如果有人绕过此类检查会产生安全隐患。

例如...

控制器

public ActionResult GenerateFile(MyParams myParams)
{
    var template = Server.MapPath(PPT_ROOT + "/template.pptx");
    IEnumerable<Order> orders = Model.GetOrders(myparams);

    if(!orders.Any()){
        Response.StatusCode = (int)HttpStatusCode.NotFound
        Response.StatusDescription = HttpStatusCode.NotFound.ToString();
        Response.TrySkipIisCustomErrors = true;
        return EmptyResult;
    } 

    var pptResults = GeneratePowerpointFile(orders);
    return new File(pptResults.Content, "application/vnd.ms-powerpoint", pptResults.FileName);
}
于 2014-01-20T14:33:53.660 回答
1
if (count==0) return View();
else return File(...)

这不行吗?

于 2014-01-03T02:43:06.420 回答
1

如果 orders.Count() 为 0 或发生其他错误,我建议重定向用户。像这样的东西。

public ActionResult GenerateFile(MyParams myParams)
{
    var template = Server.MapPath(PPT_ROOT + "/template.pptx");
    IEnumerable<Order> orders = Model.GetOrders(myparams);
    if(orders.Count() == 0){
       return RedirectToAction("Orders","ordersError",new { ID = "Error message"});
    }else{
       var pptResults = GeneratePowerpointFile(orders);
       return File(pptResults.Content, "application/vnd.mspowerpoint",pptResults.FileName);
    }
}

因此,您创建了一个显示您的错误消息的信息化 ordersError 视图。

于 2014-01-03T15:00:20.327 回答
1

也许这篇文章可能有用: 使用 Javascript/jQuery 下载文件

我相信JQuery 文件下载插件值得关注,它可以优雅地处理错误 :) 也可以查看它的在线演示...

于 2014-01-19T17:46:45.763 回答
1

如果您甚至必须处理内部服务器错误,则必须设置一个自定义过滤器,将其应用于您的控制器方法,该方法拦截与磁盘相关的错误或任何错误,并优雅地处理,并返回您的视图一些有意义的数据消息。

请参阅这篇关于创建 asp.net mvc 过滤器和相关 javascript 代码的帖子。

ASP.NET MVC Ajax 错误处理

于 2014-01-17T12:57:11.830 回答
1

@Anthony Shaw的回答很好,但有两个问题:

  1. 如果您使用try{} catch{}然后在导出文件过程中出现错误会发生什么?
  2. 如何在保持当前页面的同时更友好地返回消息?

答案是你应该用Ajax两个步骤来实现它:

  1. 您应该调用 ajax 来生成一个文件,并将该内存数据存储到SessionorTempData中。

阿贾克斯

$ajax({
    cache: false,
    url: '/Initiative/GenerateFile',
    data: GenerateParams(), 
    success: function (data){
         var response = JSON.parse(data);
         if(response.IsSuccesful) {
           window.location = '/Initiative/DownloadFile?fileGuid=' + response.FileGuid 
                           + '&filename=' + response.FileName;
         }else{
           alert(response.ErrorMessage);
         }
    }
});

控制器

    public ActionResult GenerateFile(MyParams myParams)
    {
        IEnumerable<Order> orders = Model.GetOrders(myparams);
        if (orders.Count() == 0)
        {
            return new JsonResult
            {
                Data = new { IsSuccesful = false, ErrorMessage = "No orders" }
            };
        }
        try
        {
            var pptResults = GeneratePowerpointFile(orders);
            var guid = Guid.NewGuid().ToString();
            TempData[guid] = pptResults.Content;
            return new JsonResult
            {
                Data = new { IsSuccesful = true, FileGuid = guid, FileName = pptResults.FileName }
            };
        }
        catch (Exception err)
        {
            return new JsonResult
            {
                Data = new { IsSuccesful = false, ErrorMessage = err }
            };
        }

    }
  1. 创建一个新DownloadFile操作来读取TempData[guid]然后返回该文件。

    [HttpGet]
    public virtual ActionResult DownloadFile(string fileGuid, string fileName)
    {
        if (TempData[fileGuid] != null)
        {
            var data = TempData[fileGuid] as byte[];
            return File(data, "application/vnd.ms-powerpoint", fileName);
        }
        else
        {
            return new EmptyResult();
        }
    }
    

阅读通过 AJAX MVC 下载 Excel 文件的好文章

于 2021-01-08T07:49:35.360 回答