2008-10-25 10 views
16

¿Cuál es la mejor manera de manejar a un visitante construyendo su propia URL y reemplazando lo que esperamos que sea una identificación con lo que quiera?ASP.Net MVC - manejo de parámetros de URL incorrectos

Por ejemplo:

ASP.Net MVC - handling bad URL parameters

Pero el usuario podría fácilmente reemplazar la URL con:

https://stackoverflow.com/questions/foo

he pensado en hacer todos los parámetros del controlador Función a String, y usando Integer.TryParse() en ellos - si eso pasa entonces tengo una identificación y puedo continuar; de lo contrario, puedo redireccionar al usuario a una Vista desconocida/no encontrada o índice.

Stack Overflow lo maneja muy bien, y me gustaría también, ¿cómo lo hace, o qué sugeriría?

Respuesta

12

He aquí un ejemplo de una ruta como la suya, con una restricción en el número:

routes.MapRoute(
    "Question", 
    "questions/{questionID}", 
    new { controller = "StackOverflow", action = "Question" }, 
    new { questionID = @"\d+" } //Regex constraint specifying that it must be a number. 
); 

Aquí establecemos la IdPregunta que tiene al menos un número. Esto también bloqueará cualquier url que contenga algo más que un entero, y también evitará la necesidad de un int nullable.

Nota: Esto no tiene en cuenta los números que superan el rango de Int32 (-2147483647 - +2147483647). Dejo esto como un ejercicio para que el usuario lo resuelva. :)

Si el usuario ingresa la url "questions/foo", no golpearán la acción de la pregunta, y se saldrán de ella, porque falla la restricción del parámetro. Se puede manejar más abajo en una ruta de cajón de sastre/predeterminada si desea:

routes.MapRoute(
    "Catchall", 
    "{*catchall}", // This is a wildcard routes 
    new { controller = "Home", action = "Lost" } 
); 

Esto enviará al usuario la acción Perdido en el controlador principal. Se puede encontrar más información sobre el comodín en here.

NB: El Catchall debe residir como la ÚLTIMA ruta. Al colocarlo más arriba en la cadena, significará que manejará todos los demás debajo de ella, dada la naturaleza perezosa de las rutas en ASP.NET MVC.

+2

esto parece una muy buena manera de manejar usuarios locos =) – JOBG

+2

En lugar de la última línea: 'new {questionID = @ "\ d {1,}"}', Scott Hanselman usa una sintaxis ligeramente más corta de: 'new { questionID = @ "\ d +"} 'significa lo mismo. Fuente: http://www.asp.net/learn/mvc-videos/video-7093.aspx – Andrew

+1

Sí, los dos son más o menos lo mismo. Tiendo a poner los míos en llaves de esa manera porque creo dinámicamente mis rutas desde la base de datos, y me ahorra un poco de lógica cuando quiero especificar explícitamente la cantidad máxima de dígitos. –

0

El problema con este enfoque es que todavía pueden pasar un entero que no se asigna a una página. Solo devuelve un 404 si lo hacen, tal como harías con "foo". No es algo de lo que preocuparse a menos que tenga claras implicaciones de seguridad.

+0

Claro, tendría que comprobar que el número entero es válido, pero está usando String como el parámetro de la función ¿te indica el camino a seguir? - El ejemplo TaskList (http://www.asp.net/learn/mvc/tutorial-01-cs.aspx ~ 35min 43s) escribe fuertemente el ID en Integer y esto da como resultado un error cuando se pasa 'foo': o/ – Andrew

3

En ASP.NET MVC, puede definir un filtro que implemente la interfaz IActionFilter. Podrás decorar tu acción con este atributo para que se ejecute en, antes o después de tu acción.

En su caso, deberá definir que se ejecute "antes" de su acción. Entonces, podrá cancelarlo si hay un error en los parámetros pasados. El beneficio clave aquí es que solo escribe el código que verifica los parámetros pasados ​​una vez (es decir, lo define en su filtro) y lo usa donde lo desee en las acciones de su controlador.

Leer más sobre MVC filtra aquí: http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx

2

Puede especificar restricciones como expresiones regulares o definir restricciones personalizadas. Echar un vistazo a esta entrada del blog para obtener más información:

http://weblogs.asp.net/stephenwalther/archive/2008/08/06/asp-net-mvc-tip-30-create-custom-route-constraints.aspx

Usted todavía tendrá que hacer frente a la situación en la que 43243 ID no se asigna a todo aquello que pueda ser tratado como un IActionFilter o en su controlador directamente.

5

Aquí hay alguna información útil que podría ayudar. Si usted tiene un método de acción

public ActionResult Edit(int? id) 
{} 

luego, si alguien escribe

/Home/Edit/23 

el parámetro id serán 23. Sin embargo, si alguien escribe

/Home/Edit/Junk 

luego de identificación se null, que es muy bueno. Pensé que arrojaría un error de lanzamiento o algo así. Significa que si id no es un valor nulo, entonces es un número entero válido y se puede pasar a sus servicios, etc. para la interacción db.

Espero que esto le proporcione alguna información que he encontrado durante la prueba.

+0

Además, habrá un error de modelo en ModelState que refleja el problema con el parámetro "id". –

Cuestiones relacionadas