重写AuthorizeAttribute后,能否通过RedirectResult跳转至共享错误视图?
嘿,我来帮你把这些问题理清楚:
1. 能不能用RedirectResult直接重定向到共享错误视图?
答案是不行。你当前代码里直接写"~/Shared/NotAuthorized.cshtml"会触发404错误——ASP.NET MVC的视图文件(.cshtml)不能直接通过URL访问,它们需要由控制器的Action方法触发渲染后,才能输出给客户端。RedirectResult是告诉浏览器跳转到一个具体的URL,而非直接返回视图内容。
2. 是否必须创建Error控制器?
不是必须,但这是最符合MVC设计模式的规范做法。当然你也有更简洁的选择:不需要跳转,直接在OnAuthorization里返回ViewResult来渲染共享视图,这样URL不会改变,用户体验更流畅。
两种实现方式示例:
方式一:直接返回共享视图(无需额外控制器)
public override void OnAuthorization(AuthorizationContext filterContext) { // 检查授权失败的逻辑 if (!IsAuthorized(filterContext)) { // 直接返回共享视图,无需跳转 filterContext.Result = new ViewResult { ViewName = "~/Views/Shared/NotAuthorized.cshtml", ViewData = filterContext.Controller.ViewData, TempData = filterContext.Controller.TempData }; // 注意:这里不要调用base.OnAuthorization,因为我们已经处理了结果 return; } base.OnAuthorization(filterContext); }
方式二:创建Error控制器(推荐,更规范)
先创建一个Error控制器:
public class ErrorController : Controller { public ActionResult NotAuthorized() { // 直接返回共享视图,因为Shared目录下的视图会被自动查找 return View("NotAuthorized"); } }
再修改AuthorizeAttribute的代码,跳转到这个Action:
public override void OnAuthorization(AuthorizationContext filterContext) { if (!IsAuthorized(filterContext)) { // 利用路由生成适配环境的URL string redirectUrl = filterContext.Url.Action("NotAuthorized", "Error"); filterContext.Result = new RedirectResult(redirectUrl); return; } base.OnAuthorization(filterContext); }
3. 如何编写URL确保本地测试和服务器发布后均能生效?
核心原则是不要硬编码物理路径或相对路径,而是利用ASP.NET MVC的路由机制生成URL:
- 如果用跳转(RedirectResult):使用
filterContext.Url.Action("ActionName", "ControllerName"),它会根据你的路由配置自动生成正确的URL——不管是本地的http://localhost:xxxx/Error/NotAuthorized,还是服务器上的https://yourdomain.com/Error/NotAuthorized。 - 如果直接返回视图(ViewResult):使用带波浪号的完整路径
"~/Views/Shared/NotAuthorized.cshtml",波浪号~会自动解析为应用程序根目录,完美适配不同部署环境。
另外补充:如果你的共享视图放在Views/Shared目录下,在控制器里直接写return View("NotAuthorized")就能自动找到它,但在AuthorizeAttribute里因为没有控制器上下文的直接关联,写完整路径会更稳妥。
内容的提问来源于stack exchange,提问作者Grizzly
相关产品推荐
相关产品推荐

