2011-06-30 10 views
11

ASP.NET MVC parece alentarme a utilizar cadenas codificadas para referirme a controladores y acciones.Evite nombres de controlador y acción de codificación fija

Por ejemplo, en un controlador:

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

o, en una vista:

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

no quiero cadenas no modificables por todo el código. ¿Qué puedo hacer para evitar esto?

+1

No hay ningún problema con este mi humilde opinión. En algún momento, debe indicarle al código que apunte a una clase o función específica. – Timbo

+2

@Badger el problema es qué pasa si cambia el nombre de sus acciones/controladores. Luego tiene que encontrar de alguna manera todas las cadenas codificadas para actualizarlas y no puede confiar en que el compilador le diga que se ha perdido algo. – Dolbz

+1

ReSharper puede hacer que este no problema – driushkin

Respuesta

13

Me parece que desea utilizar redirecciones fuertemente tipadas. Hice una llamada RedirectionHelper clase auxiliar estática que tiene el siguiente método:

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); 
} 

La única advertencia es que usted tendrá que utilizar la biblioteca de futuros Microsoft.Web.Mvc disponibles sobre Nuget.

Ahora, para su controlador, crear un controlador de base de que todos los controladores heredan de que tiene este método:

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

Ahora, en su acción, todo lo que tiene que hacer es decir:

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

Del mismo modo, puede escribir un método de extensión html que tome los mismos parámetros y construya su etiqueta de anclaje.

Como dijo anteriormente que quería, cuando cambia los nombres de Controlador o Acción, su proyecto se interrumpirá en tiempo de compilación y le mostrará dónde ocurren las interrupciones. Sin embargo, esto solo ocurrirá en los controladores, ya que las vistas no se compilan.

Espero que esto ayude!

+0

Nice :) Publiqué la misma solución unos segundos después –

+0

nice - mucho mejor que jugar con las plantillas t4 - que apesta si soy sincero – iwayneo

+0

Nota: Para que esto funcione, ExpressionHelper debe ser 'Microsoft.Web.Mvc .Internal.ExpressionHelper', ** no ** 'System.Web.Mvc.ExpressionHelper'. –

5

Mira T4MVC esto genera clases para que pueda tener acciones inflexible de tipos y los nombres del controlador. Como todavía se trata de una asignación a una cadena, la refactorización no causará que los nombres en sus vistas se actualicen si cambia un nombre de controlador, por ejemplo.

Después de regenerar obtendrá errores de compilación debido a que los nombres desaparecen de las clases generadas, por lo que sigue siendo útil en la refactorización y atrapa problemas que puede pasar por alto al utilizar cadenas codificadas.

3

No estoy seguro si alguien ya ha añadido un método de extensión de uno de los proyectos relacionados con ASP.NET MVC pero aquí hay un trozo de código que puede utilizar para crear su propio método de extensión:

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); 
    } 

No hay parámetros fusionando la lógica, por lo que deberá agregarla por su cuenta.

ACTUALIZACIÓN: @ mccow002 añadió una solución similar unos pocos segundos antes que yo, así que creo que la solución debe ser aceptada.

0

Sé que este es un tema antiguo, pero cuando estaba buscando una respuesta para ASP.NET 5 este tema apareció por primera vez. No hay necesidad de codificar más, sólo tiene que utilizar nombredel

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

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

Esto no funcionará si alguien anula el nombre de la acción mediante el atributo ActionName, p. Ej. '[Nombre de la acción (" NewActionName ")]' –

+0

@DavidSpence Sí, tampoco funcionará con los controladores tal cual, debe implementar un método de extensión que corte el sufijo de "Controlador". Sin embargo, eso es algo. – Serhii

Cuestiones relacionadas