Избегайте жесткого кодирования контроллера и имен действий - PullRequest
12 голосов
/ 30 июня 2011

ASP.NET MVC, кажется, побуждает меня использовать жестко запрограммированные строки для ссылки на контроллеры и действия.

Например, в контроллере:

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

или в представлении:

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

Я не хочу, чтобы во всем коде были жестко закодированные строки,Что я могу сделать, чтобы избежать этого?

Ответы [ 5 ]

14 голосов
/ 30 июня 2011

Мне кажется, что вы хотите использовать строго типизированные перенаправления.Я создал статический вспомогательный класс 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, который принимает те же параметры и создает ваш тег привязки.

Как вы сказали выше, что вы хотели, когда вы изменяете имена контроллера или действия, ваш проект будетперерыв во время компиляции и покажет вам, где происходят перерывы.Однако это будет происходить только в контроллерах, так как представления не компилируются.

Надеюсь, это поможет!

5 голосов
/ 30 июня 2011

Посмотрите на T4MVC , это генерирует классы, чтобы вы могли иметь строго типизированные действия и имена контроллеров. Поскольку это по-прежнему просто сопоставление со строкой, рефакторинг не приведет к обновлению имен в ваших представлениях, например, если вы измените имя контроллера.

После регенерации вы получите ошибки компиляции из-за исчезновения имен из ваших сгенерированных классов, хотя это все еще полезно при рефакторинге и обнаруживает проблемы, которые вы можете пропустить, используя жестко закодированные строки.

4 голосов
/ 30 июня 2011
3 голосов
/ 01 июля 2011

Не уверен, что кто-то уже добавил метод расширения в один из проектов, связанных с 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 добавил похожее решение за несколько секунд до меня, поэтому я думаю, что его решение должно быть принято.

0 голосов
/ 19 мая 2016

Я знаю, что это старая тема, но когда я искал ответ для ASP.NET 5, эта тема впервые появилась. Больше не нужно жестко кодировать, просто используйте nameof

[HttpGet]
public IActionResult List()
{
   ...
   return View();
}

[HttpPost]
public IActionResult Add()
{
    ...
    return RedirectToAction(nameof(List));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...