View渲染时触发ExternalLogin Action方法报错,求正确实现方案
View渲染时调用HttpPost Action报错的解决办法
问题场景
我有如下Action方法:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult ExternalLogin() { string provider = ""; string returnUrl = null; if (returnUrl.IsNullOrWhiteSpace()) { returnUrl = Request.RawUrl; } // Request a redirect to the external login provider return new ChallengeResult(provider, Url.SurfaceAction<UmbracoIdentityAccountController>("ExternalLoginCallback", new { ReturnUrl = returnUrl })); }
尝试在View渲染时通过以下代码触发该方法:
@Html.Action("ExternalLogin", "UmbracoIdentityAccount");
但出现错误:
A public action method 'ExternalLogin' was not found on controller
错误原因
@Html.Action() 默认发起GET请求,而目标ExternalLogin方法标记了[HttpPost]特性,仅接受POST请求,因此框架无法找到匹配的Action方法,抛出上述错误。同时,该方法还带有[ValidateAntiForgeryToken]特性,即便强行改为GET请求,也会因缺少防伪令牌验证失败。
正确实现方式
方式1:通过表单提交触发POST请求(推荐)
在View中渲染表单,通过手动提交或自动提交的方式触发POST请求:
手动提交版本
@using (Html.BeginForm("ExternalLogin", "UmbracoIdentityAccount", FormMethod.Post)) { @Html.AntiForgeryToken() <button type="submit">启动外部登录</button> }
页面加载自动提交版本
如果需要页面渲染完成后自动触发,可添加JS代码自动提交表单:
@using (Html.BeginForm("ExternalLogin", "UmbracoIdentityAccount", FormMethod.Post, new { id = "autoSubmitLoginForm" })) { @Html.AntiForgeryToken() } <script> window.onload = function() { document.getElementById('autoSubmitLoginForm').submit(); }; </script>
方式2:新增GET版本Action(不推荐,存在安全风险)
若必须使用@Html.Action()触发,可新增一个不带[HttpPost]和[ValidateAntiForgeryToken]的GET版本Action。但需注意:外部登录逻辑通过GET触发可能存在CSRF安全风险,仅在特殊场景下使用:
[AllowAnonymous] public ActionResult ExternalLogin() { string provider = ""; string returnUrl = null; if (returnUrl.IsNullOrWhiteSpace()) { returnUrl = Request.RawUrl; } return new ChallengeResult(provider, Url.SurfaceAction<UmbracoIdentityAccountController>("ExternalLoginCallback", new { ReturnUrl = returnUrl })); }
内容的提问来源于stack exchange,提问作者None
相关产品推荐
相关产品推荐

