2009-06-30 5 views
5

I tienen el siguiente caso donde quiero aceptar las siguientes rutas deasp.net mvc - Route de cadena o int (es decir/Tipo/23 o/Tipo/sombreros)

'/type/view/23' or '/type/view/hats' 

donde 23 es el ID para sombreros.

El controlador es como la siguiente:

public class TypeController 
{ 
    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult View(int id) 
    { 
     ... 
    } 
} 

Ahora si pasan en 23 no hay problemas. Si pasan sombreros, tengo algo de trabajo que hacer. Ahora me preguntaba si en este caso traduciría sombreros a 23 usando un ActionFilter que mira si el valor pasó porque el ID es un int (de ser así, compruebe que existe en la base de datos) o si se ve una cadena la base de datos para saber cuál es la identificación de la cadena que se ha pasado. En cualquier caso, si no se encuentra una coincidencia, me gustaría redirigir al usuario a una acción diferente.

En primer lugar es el enfoque que he nombrado correcto, en segundo lugar es posible hacer una redirección desde dentro de un ActionFilter.

Saludos Anthony

Respuesta

4

Cambia tu firma para aceptar una cadena. Luego verifica si el valor de id es un int. Si es así, busque por id, si no busca por nombre. Si no encuentra una coincidencia, haga su redirección.

public class TypeController 
{ 
    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult View(string id) 
    { 
     Product product = null; 
     int productID = -1; 
     if (int.TryParse(id, out productID)) 
     { 
      product = db.Products 
         .Where(p => p.ID == productID) 
         .SingleOrDefault(); 
     } 
     else 
     { 
      product = db.Products 
         .Where(p => p.Name == id) 
         .SingleOrDefault(); 
     } 

     if (product == null) 
     { 
      return RedirectToAction("Error"); 
     } 
     ... 
    } 
} 

La razón por la que me gustaría hacer esto es que con el fin de saber qué controlador/acciones a aplicar, el marco se va a buscar uno que coincida con la firma de los datos de ruta que ha pasado. Si Don No tiene una firma que coincida, en este caso una que toma una cadena, obtendrá una excepción antes de invocar cualquiera de sus filtros. Desafortunadamente, no creo que pueda tener uno que tome una cadena y otro que tome una int. En ese caso, la estructura no podrá decir cuál debería coincidir si se pasa un solo parámetro, al menos si es un número, eso es. Al convertirlo en un parámetro de cadena y manejar la traducción usted mismo, permite que el marco haga su trabajo y obtiene el comportamiento que desea, sin necesidad de filtros.

+1

a pensar en encontrar una manera para que el marco para hacer el trabajo, podría tener dos derrotas como la siguiente: this._Routes.MapRoute ("TypeInt" , "tipo/vista/{id}", nuevo {controlador = "Tipo", acción = "ViewInt"}, nuevo {página = @ "^ \ d + $"}); this._Routes.MapRoute ("TypeString", "tipo/vista/{id}", nuevo {controlador = "Tipo", acción = "ViewString"}); ¿Valdría la pena hacer esto? o ¿crees que solo haces el análisis de prueba? –

+0

No veo lo que gana agregando complicaciones a la infraestructura de enrutamiento, excepto que hace el análisis sintáctico para usted. No soy lo suficientemente inteligente como para saber si funcionaría sin realmente probarlo.Personalmente, probablemente tenga dos acciones diferentes, View y ViewByName, que usan el mismo método privado para generar los datos una vez que se ha encontrado el producto correcto. Para mí eso sería aún más simple y claro. – tvanfosson

0

Inseguro que pueden hacer esto. Creo que tendrías que pasar una cadena y luego verificar si es numérica, pero puede haber una forma mejor.

En cuanto a la reorientación de uso

return RedirectToAction("MyProfile", "Profile"); 

Puede pasar valores de ruta como parte de la llamada RedirectToAction lo que puede pasar en identificadores o nombres, etc, si eso es lo que se requiere.

Hay otros como redirigir a las rutas que también pueden ser útiles para lo que quieres.

+0

Con el cambio de dirección que estaba pensando en hacer esto desde dentro de la actionfilter –

Cuestiones relacionadas