【问题标题】:Ajax.ActionLink can't find public controller method because it's asyncAjax.ActionLink 找不到公共控制器方法,因为它是异步的
【发布时间】:2017-01-13 09:43:50
【问题描述】:

我认为有以下 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);
        }

方法被命中,但返回后,没有文件发送到浏览器并抛出异常:

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)

这里发生了什么?

【问题讨论】:

    标签: asp.net-mvc-4 async-await asp.net-ajax


    【解决方案1】:

    我建议您不要使用 AJAX 下载文件。即使调用成功,您对成功回调中的二进制内容也无能为力,并且无法将其保存到客户端计算机。例如,在您的 AjaxLink 中,您似乎指定了 UpdateTargetId = "modal-container" 参数,但我想知道如果您的控制器操作返回二进制流,您希望在此 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
    {
        ...
    }
    

    【讨论】:

    • 感谢您的时间和建议。我的 DocumentController 类有一个名为 DownloadDocument 的公共方法,并且该方法被命中,如果我在其上放置断点,我可以看到它正在运行并返回。以前在同步版本中使用的方法,我只是想让它异步运行。我使用 ajax 是因为我希望它是一个链接,而不是提交按钮,只是为了美观。
    • 你可以让按钮看起来像一个链接没有任何问题:stackoverflow.com/questions/1367409/…
    • 另外,从我所见,您似乎正在使用 asp.net mvc 4。我不太确定它是否支持开箱即用的异步操作。你可以用 mvc 5 试试这个吗?它应该可以工作。
    猜你喜欢
    • 2013-06-01
    • 2013-05-15
    • 2016-02-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多