避免硬编码控制器和操作名称

ASP.NET MVC似乎鼓励我使用硬编码字符串来引用控制器和操作。

例如,在控制器中:

return RedirectToAction("Index", "Home"); 

或者,在一个视图中:

 Html.RenderPartial("Index", "Home"); 

我不想在我的代码中使用硬编码字符串。 我该怎么做才能避免这种情况?

听起来我想要使用强类型重定向。 我创建了一个名为RedirectionHelper的静态助手类,它具有以下方法:

 public static string GetUrl(Expression> action, RequestContext requestContext, RouteValueDictionary values = null) where T : Controller { UrlHelper urlHelper = new UrlHelper(requestContext); RouteValueDictionary routeValues = ExpressionHelper.GetRouteValuesFromExpression(action); if (values != null) foreach (var value in values) routeValues.Add(value.Key, value.Value); return urlHelper.RouteUrl(routeValues); } 

唯一需要注意的是,您必须使用Nuget上提供的Microsoft.Web.Mvc期货库。

现在,对于您的控制器,创建一个所有控制器inheritance的基本控制器具有此方法:

 protected RedirectResult RedirectToAction(Expression> action, RouteValueDictionary values = null) where T : Controller { return new RedirectResult(RedirectionHelper.GetUrl(action, Request.RequestContext, values)); } 

现在,在你的行动中,你所要做的就是说:

 return RedirectToAction(x => x.Index()); 

同样,您可以编写一个html扩展方法,该方法接受相同的参数并构建您的锚标记。

就像你上面所说的那样,当你改变Controller或Action名称时,你的项目将在编译时中断并显示中断发生的位置。 但是,这只会出现在控制器中,看看视图是如何编译的。

希望这可以帮助!

查看T4MVC,这会生成类,因此您可以使用强类型操作和控制器名称。 由于它仍然只是字符串的映射,因此,如果更改控制器名称,则重构不会导致视图中的名称更新。

重新生成后,由于名称从生成的类中消失,您将收到编译错误,因此它仍然可用于重构并捕获使用硬编码字符串可能遗漏的问题。

试试T4MVC: http ://mvccontrib.codeplex.com/wikipage?title = T4MVC

不确定是否有人已经向ASP.NET MVC相关项目之一添加了扩展方法,但这里有一段代码可用于创建自己的扩展方法:

 public RedirectToRouteResult RedirectToAction(Expression> action, RouteValueDictionary routeValues) where TController : Controller { RouteValueDictionary rv = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action); return RedirectToAction((string)rv["Action"], (string)rv["Controller"], routeValues ?? new RouteValueDictionary()); } public ActionResult Index() { return RedirectToAction(x => x.Index(), null); } 

没有参数合并逻辑,因此您必须自己添加它。

更新:@ mccow002在我前几秒添加了一个类似的解决方案,所以我认为他的解决方案应该被接受。

我知道这是一个古老的话题,但当我在寻找ASP.NET 5的答案时,这个主题首次出现。 不再需要硬编码,只需使用nameof即可

 [HttpGet] public IActionResult List() { ... return View(); } [HttpPost] public IActionResult Add() { ... return RedirectToAction(nameof(List)); }