ASP.NET MVC似乎是鼓励我使用硬编码字符串是指控制器和动作。避免硬编码控制器和动作名称
例如,在一个控制器:
return RedirectToAction("Index", "Home");
,或者在一个视图:
Html.RenderPartial("Index", "Home");
我不希望都在我的代码硬编码字符串。我能做些什么来避免这种情况?
ASP.NET MVC似乎是鼓励我使用硬编码字符串是指控制器和动作。避免硬编码控制器和动作名称
例如,在一个控制器:
return RedirectToAction("Index", "Home");
,或者在一个视图:
Html.RenderPartial("Index", "Home");
我不希望都在我的代码硬编码字符串。我能做些什么来避免这种情况?
像你想使用强类型的重定向这听起来我。我做了一个静态辅助类叫做RedirectionHelper具有以下方法:
public static string GetUrl<T>(Expression<Action<T>> 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);
}
唯一需要注意的是,你将不得不使用可用的Microsoft.Web.Mvc期货库出来的NuGet。现在
,为您的控制器,创建一个基控制器,所有控制器从继承了这种方法:
protected RedirectResult RedirectToAction<T>(Expression<Action<T>> action, RouteValueDictionary values = null) where T : Controller
{
return new RedirectResult(RedirectionHelper.GetUrl(action, Request.RequestContext, values));
}
现在,在你的行动,你需要做的是说:
return RedirectToAction<Controller>(x => x.Index());
同样,你可以编写一个HTML扩展方法,它接受相同的参数并构建你的锚标签。
就像你在上面,你想,当你改变控制器或者动作名称,你的项目将打破在编译的时候,告诉你该休息发生在哪里说。但是,这只会发生在控制器中,看到视图如何编译。
希望这会有所帮助!
好:)我几秒钟后发布相同的解决方案 –
不错 - 比t4模板搞乱 - 这真的很糟糕 – iwayneo
注意:为此,ExpressionHelper必须是'Microsoft.Web.Mvc .Internal.ExpressionHelper',**不** **'System.Web.Mvc.ExpressionHelper'。 –
看T4MVC这会产生类,所以你可以有强类型的动作和控制器的名称。因为它仍然只是一个字符串映射,所以如果您更改控制器名称,重构不会导致视图中的名称更新。
再生您将获得由于从生成的类消失,但这样它仍然是有用的重构和捕捉,你可以错过使用硬编码字符串问题的名称编译错误后。
不知道是否有人已经添加一个扩展方法到ASP.NET MVC相关的项目之一,但这里有一段代码,你可以用它来创建自己的扩展方法:
public RedirectToRouteResult RedirectToAction<TController>(Expression<Action<TController>> 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<DashboardController>(x => x.Index(), null);
}
有没有参数合并逻辑,所以你必须自己添加它。
UPDATE:@ mccow002加入了类似的解决方案我之前几秒钟,所以我认为他的解决办法应该被接受。
我知道这是一个老话题,但是当我在寻找一个答案ASP.NET 5这个主题首次出现。 没有必要再进行硬编码,只需用nameof
[HttpGet]
public IActionResult List()
{
...
return View();
}
[HttpPost]
public IActionResult Add()
{
...
return RedirectToAction(nameof(List));
}
如果某人通过ActionName属性覆盖了操作名称,这将不起作用,例如'[ActionName(“NewActionName”)]' –
@DavidSpence 是的,它也不会像控制器一样工作,你需要实现扩展方法,它将切断“控制器”后缀。但是,这是一些东西。 – Serhii
没有与此恕我直言没有问题。在某些时候,你必须告诉代码指向一个特定的类或函数。 – Timbo
@Badger问题是如果你重命名你的动作/控制器。然后,您必须以某种方式找到所有硬编码的字符串来更新它们,并且您不能依靠编译器来告诉您,您错过了某些东西。 – Dolbz
ReSharper可以使这个没有问题 – driushkin