2011-08-04 28 views
29

Estoy tratando de configurar una ruta personalizada en MVC para tomar una URL desde otro sistema en el siguiente formato:¿Cómo enruto una URL con una cadena de consulta en ASP.NET MVC?

../ABC/ABC01?Key=123&Group=456

El 01 después de la segunda ABC es un número de paso esto va a cambiar y la clave y los parámetros del grupo cambiarán. Necesito dirigir esto a una acción en un controlador con la tecla numérica del paso y el grupo como parámetros. He intentado el siguiente código sin embargo, se produce una excepción:

Código:

routes.MapRoute(
    "OpenCase", 
    "ABC/ABC{stepNo}?Key={key}&Group={group}", 
    new {controller = "ABC1", action = "OpenCase"} 
); 

Excepción:

`The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.` 

Respuesta

35

No puede incluir la cadena de consulta en la ruta. Pruebe con una ruta como esta:

routes.MapRoute("OpenCase", "ABC/ABC{stepNo}", 
    new { controller = "ABC1", action = "OpenCase" }); 

Luego, en el controlador de añadir un método como este:

public class ABC1 : Controller 
{ 
    public ActionResult OpenCase(string stepno, string key, string group) 
    { 
     // do stuff here 
     return View(); 
    }   
} 

ASP.NET MVC le asignará automáticamente los parámetros de cadena de consulta a los parámetros en el método de el controlador.

4

Al definir rutas, no se puede utilizar un / al comienzo de la ruta:

routes.MapRoute("OpenCase", 
    "/ABC/{controller}/{key}/{group}", <-- Bad; see/at beginning 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

routes.MapRoute("OpenCase", 
    "ABC/{controller}/{key}/{group}", <-- Good; No/at beginning 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

Prueba esto:

routes.MapRoute("OpenCase", 
    "ABC/{controller}/{key}/{group}", 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

Luego, su acción debe verse de la siguiente manera:

public ActionResult OpenCase(int key, int group) 
{ 
    //do stuff here 
} 

Parece que estás armando el stepNo y el " ABC "para obtener un controlador que es ABC1. Es por eso que reemplacé esa sección de la URL con {controller}.

Como también tiene una ruta que define la "clave" y el "grupo", la ruta anterior también captará su URL inicial y la enviará a la acción.

1

No hay ninguna razón para usar el enrutamiento basado en querystring en el nuevo proyecto ASP.NET MVC. Puede ser útil para un proyecto antiguo que se haya convertido del clásico proyecto ASP.NET y desee conservar las URL.

Una solución puede ser el enrutamiento de atributos.

Otra solución puede estar en escritura de enrutamiento personalizado mediante la derivación de RouteBase:

public class MyOldClassicAspRouting : RouteBase 
{ 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
    if (httpContext.Request.Headers == null) //for unittest 
     return null; 

    var queryString = httpContext.Request.QueryString; 

    //add your logic here based on querystring 
    RouteData routeData = new RouteData(this, new MvcRouteHandler()); 
    routeData.Values.Add("controller", "..."); 
    routeData.Values.Add("action", "..."); 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
    //Implement your formating Url formating here 
    return null; 
    } 
} 

y registrar su clase de enrutamiento personalizado

public static void RegisterRoutes(RouteCollection routes) 
{ 
    ... 

    routes.Add(new MyOldClassicAspRouting()); 
} 
0

la consulta argumentos de cadena generalmente son específicos de ese controlador y de ese lógica de aplicación específica.

Por lo tanto, será mejor si esto no está escrito en las reglas de ruta, que son generales.

Puede incrustar la detección de cadena de consulta en el argumento de acción de la siguiente manera.

Creo que es mejor tener un Controlador para manejar StepNo.

ModelBinder asigne {id} valor al campo de id de OpenCaseArguments. El método set maneja la lógica de división de la querystring.

Y siga el enrutamiento de esta manera. Tenga en cuenta el enrutamiento obtenga su cadena de consulta en el argumento id.

routes.MapRoute(
    "OpenCase", 
    "ABC/OpenCase/{id}", 
    new {controller = "ABC", action = "OpenCase"} 
); 

He utilizado este método para obtener valores de clave de múltiples campos en la acción del controlador.

+0

Tenga en cuenta que MVC analiza automáticamente la cadena de consulta con el 'QueryStringValueProvider'. Todo lo que necesita hacer para obtener estos valores en un método de acción es agregar parámetros con el mismo nombre que las claves de cadena de consulta al método o modelo de acción. No es necesario crear su propio analizador de cadenas de consulta para esto. – NightOwl888

Cuestiones relacionadas