如何让ASP.NET MVC的Action方法默认返回不同名称的View且不修改方法?
实现ASP.NET MVC Action默认返回指定视图的方案
要实现不修改Contact控制器中ReviewAddContactPage方法的return View()代码,让它默认返回Index.cshtml视图而非同名视图,有三种实用方法:
方法一:重写控制器的View方法
直接在ContactController里重写基类的View方法,针对目标Action做特殊处理,仅对当前控制器生效:
public class ContactController : Controller { protected override ViewResult View(string viewName, string masterName, object model) { var currentAction = ControllerContext.RouteData.Values["action"].ToString(); // 仅当当前是ReviewAddContactPage方法且调用无参数View()时,指定视图为Index if (currentAction.Equals("ReviewAddContactPage", StringComparison.OrdinalIgnoreCase) && string.IsNullOrEmpty(viewName)) { return base.View("Index", masterName, model); } return base.View(viewName, masterName, model); } public ActionResult ReviewAddContactPage() { return View(); // 保持原代码不变 } }
方法二:使用自定义Action过滤器
创建一个可复用的Action过滤器,在Action执行后修改返回的视图名称,灵活性更高:
1. 定义过滤器类
public class ForceViewAttribute : ActionFilterAttribute { public string TargetView { get; set; } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); var controller = filterContext.RouteData.Values["controller"].ToString(); var action = filterContext.RouteData.Values["action"].ToString(); // 匹配目标控制器和Action if (controller.Equals("Contact", StringComparison.OrdinalIgnoreCase) && action.Equals("ReviewAddContactPage", StringComparison.OrdinalIgnoreCase)) { if (filterContext.Result is ViewResult viewResult && string.IsNullOrEmpty(viewResult.ViewName)) { viewResult.ViewName = TargetView; } } } }
2. 给目标Action添加特性
public class ContactController : Controller { [ForceView(TargetView = "Index")] public ActionResult ReviewAddContactPage() { return View(); // 保持原代码不变 } }
方法三:自定义视图引擎
通过修改视图引擎的查找规则,让目标Action优先加载指定视图,全局生效适合批量修改场景:
protected void Application_Start() { // 清除默认视图引擎,添加自定义引擎 ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new CustomRazorViewEngine()); } public class CustomRazorViewEngine : RazorViewEngine { protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var controllerName = controllerContext.RouteData.Values["controller"].ToString(); var actionName = controllerContext.RouteData.Values["action"].ToString(); if (controllerName.Equals("Contact", StringComparison.OrdinalIgnoreCase) && actionName.Equals("ReviewAddContactPage", StringComparison.OrdinalIgnoreCase)) { // 强制返回Index视图 return base.CreateView(controllerContext, "~/Views/Contact/Index.cshtml", masterPath); } return base.CreateView(controllerContext, viewPath, masterPath); } }
内容的提问来源于stack exchange,提问作者Calvin M.
相关产品推荐
相关产品推荐

