ASP.NET MVC似乎鼓励我使用硬编码字符串来引用控制器和操作。
例如,在控制器中:
return RedirectToAction("Index", "Home");
或者,在视图中:
Html.RenderPartial("Index", "Home");
我不想在我的代码中使用硬编码字符串。我该怎么做才能避免这种情况?
答案 0 :(得分:13)
听起来我想要使用强类型重定向。我创建了一个名为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);
}
唯一需要注意的是,您必须使用Nuget上提供的Microsoft.Web.Mvc期货库。
现在,对于您的控制器,创建一个基本控制器,所有控制器都从该控制器继承该方法:
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扩展方法,它接受相同的参数并构建你的锚标记。
就像上面所说的那样,当您更改Controller或Action名称时,您的项目将在编译时中断并显示中断发生的位置。但是,这只会出现在控制器中,看看视图是如何编译的。
希望这有帮助!
答案 1 :(得分:5)
查看T4MVC这会生成类,以便您可以使用强类型操作和控制器名称。由于它仍然只是字符串的映射,因此,如果更改控制器名称,则重构不会导致视图中的名称更新。
重新生成后,由于名称从生成的类中消失,您将收到编译错误,因此它仍然可用于重构并捕获使用硬编码字符串可能遗漏的问题。
答案 2 :(得分:4)
答案 3 :(得分:3)
不确定某人是否已经向其中一个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);
}
没有参数合并逻辑,所以你必须自己添加它。
更新:@ mccow002在我前几秒添加了一个类似的解决方案,所以我认为应该接受他的解决方案。
答案 4 :(得分:0)
我知道这是一个古老的主题,但当我在寻找ASP.NET 5的答案时,这个主题首次出现。 无需再进行硬编码,只需使用 nameof
即可 kileri.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("F");
try {
//set time in mili
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
sendData("S");
}
});