我的asp.net-mvc项目中有以下javascript代码和控制器操作:
使用Javascript:
$("#exportPPT").live('click', function (e) {
window.location.href = "/Initiative/GenerateFile" + GenerateParams();
});
C#Controller:
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调用,但我不知道如何在json请求中下载我的Fie()和包(如果支持的话)。
有什么建议吗?
答案 0 :(得分:10)
我会向另一个检查订单计数的控制器操作发起$ .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);
}
答案 1 :(得分: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);
}
答案 2 :(得分:1)
if (count==0) return View();
else return File(...)
不能这样吗?
答案 3 :(得分: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视图,显示你的错误信息。
答案 4 :(得分:1)
如果您必须处理内部服务器错误,则必须设置自定义过滤器,将其应用于您的控制器方法,该方法拦截磁盘相关错误或任何错误,并正常处理,并返回您的视图一些有意义的数据消息。
请参阅这篇文章,关于创建asp.net mvc过滤器以及相关的javascript代码。
答案 5 :(得分:1)
也许这篇文章可能有用: Download File Using Javascript/jQuery
我相信JQuery File Download plugin值得一些关注,它会优雅地处理错误:)看一看它的在线演示......
答案 6 :(得分:1)
@Anthony Shaw 的答案很好,但有两个问题:
try{} catch{}
那么您在导出文件过程中遇到错误会怎样?答案是您应该使用 Ajax
分两步实现:
Session
或 TempData
中。Ajax
$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 }
};
}
}
创建一个新的 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();
}
}
值得阅读的好文章Download Excel file via AJAX MVC