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

时间:2011-06-30 09:33:03

标签: c# asp.net-mvc model-view-controller asp.net-mvc-3

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

例如,在控制器中:

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

或者,在视图中:

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

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

5 个答案:

答案 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");
        }
    });