Ajax.ActionLink 找不到 public 控制器方法,因为它是异步的
Ajax.ActionLink can't find public controller method because it's async
我认为有以下 AjaxActionLink 代码:
@Ajax.ActionLink("Download", "DownloadDocument", "Document", new { Model.DocumentNumber, Model.DocumentName, TypeVisualization = TypeVisualization.Attachment }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "modal-container", LoadingElementId = "ajaxLoading" }, new { @class = "modal-link" })
然后,在我的 DocumentController 中:
[HttpPost]
public async Task<ActionResult> DownloadDocument(DownloadFileRequest request)
{
DownloadFileCommand command = new DownloadFileCommand();
Mapper.Map(UserModel, command);
Mapper.Map(request, command);
var result = await documentRepository.DownloadDocument(command);
ContentDisposition cd = new ContentDisposition
{
FileName = Server.UrlPathEncode(result.DocumentName),
Inline = request.TypeVisualization == TypeVisualization.Inline
};
return new FileContentResultWithContentDisposition(result.Content, result.MimeType, cd);
}
该方法被命中,但在它之后return,没有文件被发送到浏览器并抛出异常:
System.Web.HttpException (0x80004005): A public action method 'DownloadDocument' was not found on controller Document
en System.Web.Mvc.Controller.HandleUnknownAction(String actionName)
en System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
en System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
en System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
en System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
en System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
en System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
en System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
en System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
en System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
en System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
这是怎么回事?
我建议您不要使用 AJAX 下载文件。即使调用成功,您对成功回调中的二进制内容也无能为力,也无法将其保存到客户端计算机。例如,在您的 AjaxLink 中,您似乎已经指定了 UpdateTargetId = "modal-container"
参数,但我想知道如果您的控制器操作 returns 二进制流,您究竟希望在这个 div 中发生什么。
您可以使用 HTML 形式:
@using (Html.BeginForm("DownloadDocument", "Document", FormMethod.Post))
{
@Html.HiddenFor(x => x.DocumentNumber)
@Html.HiddenFor(x => x.DocumentName)
@Html.Hidden("TypeVisualization", TypeVisualization.Attachment)
<input type="submit" class="modal-link">Download</input>
}
现在就你的错误而言,我怀疑是不是跟async
这个动作有关。这应该开箱即用。确保操作正确放置在 DocumentController
:
中
public class DocumentController: Controller
{
...
}
我认为有以下 AjaxActionLink 代码:
@Ajax.ActionLink("Download", "DownloadDocument", "Document", new { Model.DocumentNumber, Model.DocumentName, TypeVisualization = TypeVisualization.Attachment }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "modal-container", LoadingElementId = "ajaxLoading" }, new { @class = "modal-link" })
然后,在我的 DocumentController 中:
[HttpPost]
public async Task<ActionResult> DownloadDocument(DownloadFileRequest request)
{
DownloadFileCommand command = new DownloadFileCommand();
Mapper.Map(UserModel, command);
Mapper.Map(request, command);
var result = await documentRepository.DownloadDocument(command);
ContentDisposition cd = new ContentDisposition
{
FileName = Server.UrlPathEncode(result.DocumentName),
Inline = request.TypeVisualization == TypeVisualization.Inline
};
return new FileContentResultWithContentDisposition(result.Content, result.MimeType, cd);
}
该方法被命中,但在它之后return,没有文件被发送到浏览器并抛出异常:
System.Web.HttpException (0x80004005): A public action method 'DownloadDocument' was not found on controller Document
en System.Web.Mvc.Controller.HandleUnknownAction(String actionName)
en System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
en System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
en System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
en System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
en System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
en System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
en System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
en System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
en System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
en System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
en System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
这是怎么回事?
我建议您不要使用 AJAX 下载文件。即使调用成功,您对成功回调中的二进制内容也无能为力,也无法将其保存到客户端计算机。例如,在您的 AjaxLink 中,您似乎已经指定了 UpdateTargetId = "modal-container"
参数,但我想知道如果您的控制器操作 returns 二进制流,您究竟希望在这个 div 中发生什么。
您可以使用 HTML 形式:
@using (Html.BeginForm("DownloadDocument", "Document", FormMethod.Post))
{
@Html.HiddenFor(x => x.DocumentNumber)
@Html.HiddenFor(x => x.DocumentName)
@Html.Hidden("TypeVisualization", TypeVisualization.Attachment)
<input type="submit" class="modal-link">Download</input>
}
现在就你的错误而言,我怀疑是不是跟async
这个动作有关。这应该开箱即用。确保操作正确放置在 DocumentController
:
public class DocumentController: Controller
{
...
}