Los puntos en URL causan 404 con ASP.NET mvc e IIS

Tengo un proyecto que requiere que mis URL tengan puntos en la ruta. Por ejemplo, puedo tener una URL como www.example.com/people/michael.phelps

Las URL con el punto generan un 404. Mi ruta está bien. Si paso en michaelphelps, sin el punto, todo funciona. Si agrego el punto obtengo un error 404. El sitio de muestra se ejecuta en Windows 7 con IIS8 Express. URLScan no se está ejecutando.

Intenté agregar lo siguiente a mi web.config:

   

Desafortunadamente eso no hizo la diferencia. Acabo de recibir un error 404.0 No encontrado.

Este es un proyecto de MVC4, pero no creo que sea relevante. Mi enrutamiento funciona bien y los parámetros que espero que estén allí, hasta que incluyan un punto.

¿Qué debo configurar para poder tener puntos en mi URL?

Lo conseguí trabajando editando los controladores HTTP de mi sitio. Para mis necesidades, esto funciona bien y resuelve mi problema.

Simplemente agregué un nuevo controlador HTTP que busca criterios de ruta específicos. Si la solicitud coincide, se envía correctamente a .NET para su procesamiento. Estoy mucho más feliz con esta solución que el URLRewrite hackear o habilitar RAMMFAR.

Por ejemplo, para que .NET procese la URL http://www.example.com/people/michael.phelps agregue la siguiente línea a la web.config de su sitio dentro del elemento system.webServer / handlers :

  

Editar

Hay otras publicaciones que sugieren que la solución a este problema es RAMMFAR o RunAllManagedModulesForAllRequests . Al habilitar esta opción, se habilitarán todos los módulos administrados para todas las solicitudes. Eso significa que los archivos estáticos, como imágenes, archivos PDF y todo lo demás, serán procesados ​​por .NET cuando no sea necesario. Esta opción es mejor dejarla a menos que tenga un caso específico para ella.

Después de hurgar, descubrí que relaxedUrlToFileSystemMapping no funcionaba para mí, lo que funcionó en mi caso fue configurar RAMMFAR en true, lo mismo es válido para (.net 4.0 + mvc3) y (.net 4.5 + mvc4).

   

Tenga en cuenta al establecer RAMMFAR verdadera publicación Hanselman sobre RAMMFAR y el rendimiento

Creo que debes establecer la propiedad relaxedUrlToFileSystemMapping en tu web.config. Haack escribió un artículo sobre esto hace un momento (y hay otras publicaciones de SO que hacen los mismos tipos de preguntas)

   

Simplemente agregue esta sección a Web.config, y todas las solicitudes a la ruta / {* pathInfo} serán manejadas por el controlador especificado, incluso cuando haya puntos en pathInfo. (tomado del ejemplo ServiceStack MVC Host Web.config y esta respuesta https://stackoverflow.com/a/12151501/801189 )

Esto debería funcionar tanto para IIS 6 como para 7. Podría asignar manejadores específicos a diferentes rutas después de la ‘ruta’ modificando path = “*” en elementos ‘add’

                 

Me quedé atascado en este tema durante mucho tiempo siguiendo todos los diferentes remedios sin ningún resultado.

Noté que al agregar una barra inclinada [/] al final de la URL que contenía los puntos [.], No arrojó un error 404 y realmente funcionó.

Finalmente resolví el problema usando un reescritor de URL como IIS URL Rewrite para observar un patrón en particular y anexar la barra de entrenamiento.

Mi URL se ve así: /Contact/~firstname.lastname por lo que mi patrón es simplemente: /Contact/~(.*[^/])$

Recibí esta idea de Scott Forsyth, consulte el siguiente enlace: http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path

MVC 5.0 Solución.

Muchas de las respuestas sugeridas no parecen funcionar en MVC 5.0.

Como el problema del punto 404 en la última sección puede resolverse cerrando esa sección con una barra al final, este es el pequeño truco que uso, limpio y simple.

Mientras mantiene un marcador de posición conveniente en su punto de vista:

 @Html.ActionLink("Change your Town", "Manage", "GeoData", new { id = User.Identity.Name }, null) 

agregue un poco de jquery / javascript para hacer el trabajo:

  

tenga en cuenta la barra al final, que es responsable de cambiar

 http://localhost:51003/GeoData/Manage/user@foo.com 

dentro

 http://localhost:51003/GeoData/Manage/user@foo.com/ 

Respuesta súper fácil para aquellos que solo tienen esto en una página web. Edite su actionlink y a + “/” al final del mismo.

  @Html.ActionLink("Edit", "Edit", new { id = item.name + "/" }) | 

Es posible que desee pensar en usar guiones en lugar de puntos.

En Pro ASP MVC 3 Framework , sugieren lo siguiente sobre la creación de URL amigables:

Evite símbolos, códigos y secuencias de caracteres. Si quiere un separador de palabras, use un guion (/ my-great-article). Los subrayados son hostiles, y los espacios codificados con URL son extraños (/ my + great + article) o desagradables (/ my% 20great% 20article).

También menciona que las URL deben ser fáciles de leer y cambiar para los humanos. Tal vez una razón para pensar en usar un guión en lugar de un punto también proviene del mismo libro:

No use extensiones de nombre de archivo para páginas HTML (.aspx o .mvc), pero sírvalas para tipos de archivos especializados (.jpg, .pdf, .zip, etc.). Los navegadores web no se preocupan por las extensiones de nombre de archivo si configura el tipo MIME de forma apropiada, pero los humanos todavía esperan que los archivos PDF finalicen con .pdf

Entonces, aunque un período aún es legible para los humanos (aunque es menos legible que los guiones, IMO), podría ser un poco confuso / engañoso dependiendo de lo que ocurra después del período. ¿Qué pasa si alguien tiene un apellido de zip? Entonces la URL será /John.zip en lugar de / John-zip, algo que puede ser engañoso incluso para el desarrollador que escribió la aplicación.

¿Sería posible cambiar tu estructura de URL?
Para lo que estaba trabajando intenté una ruta para

 url: "Download/{fileName}" 

pero falló con cualquier cosa que tuviera a. en eso.

Cambié la ruta a

  routes.MapRoute( name: "Download", url: "{fileName}/Download", defaults: new { controller = "Home", action = "Download", } ); 

Ahora puedo poner localhost:xxxxx/File1.doc/Download y funciona bien.

Mis ayudantes en la vista también se dieron cuenta

  @Html.ActionLink("click here", "Download", new { fileName = "File1.doc"}) 

eso hace un enlace al localhost:xxxxx/File1.doc/Download format también.

Tal vez podría poner una palabra innecesaria como “/ view” o acción al final de su ruta para que su propiedad pueda terminar con un final / algo así como /mike.smith/view

Intenté todas las soluciones anteriores, pero ninguna de ellas funcionó para mí. Lo que funcionó fue desinstalar versiones de .NET> 4.5, incluidas todas sus versiones multilingües; Eventualmente agregué las versiones más nuevas (solo en inglés) pieza por pieza. En este momento, las versiones instaladas en mi sistema son las siguientes:

  • 2.0
  • 3.0
  • 3.5 4
  • 4.5
  • 4.5.1
  • 4.5.2
  • 4.6
  • 4.6.1

Y todavía está trabajando en este punto. Tengo miedo de instalar 4.6.2 porque podría estropear todo.

Así que solo pude especular que 4.6.2 o todas esas versiones no inglesas estaban estropeando mi configuración.

HTH alguien.

Pude resolver mi versión particular de este problema (tenía que hacer /customer.html route to / customer, las barras diagonales no permitidas) usando la solución en https://stackoverflow.com/a/13082446/1454265 , y sustituyendo la ruta = “*. html”.

Como solución, también podría considerar la encoding a un formato que no contenga símbolo . , como base64.

En js se debe agregar

 btoa(parameter); 

En el controlador

 byte[] bytes = Convert.FromBase64String(parameter); string parameter= Encoding.UTF8.GetString(bytes); 

Agregue la regla de reescritura de URL al archivo web.config. Debe tener el módulo de reescritura de URL ya instalado en IIS. Use la siguiente regla de reescritura como inspiración para usted.

                  

Además, (relacionado) verifique el orden de las asignaciones de su controlador. Tuvimos un .ashx con un .svc (por ejemplo /foo.asmx/bar.svc/path) en la ruta después de él. El mapeo .svc fue primero así que 404 para la ruta .svc que coincidía antes de .asmx. No pensé demasiado, pero tal vez la URL que codifica el camino se encargaría de esto.

Dependiendo de cuán importante es para usted mantener su URI sin cadenas de consulta, también puede simplemente pasar el valor con puntos como parte de la cadena de consulta, no como el URI.

Por ejemplo, http://www.example.com/personas?nombre=michael.phelps funcionará, sin tener que cambiar ninguna configuración ni nada.

Pierdes la elegancia de tener un URI limpio, pero esta solución no requiere cambiar o agregar configuraciones o manejadores.

 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Web.Mvc; namespace WebApplication1.Controllers { [RoutePrefix("File")] [Route("{action=index}")] public class FileController : Controller { // GET: File public ActionResult Index() { return View(); } [AllowAnonymous] [Route("Image/{extension?}/{filename}")] public ActionResult Image(string extension, string filename) { var dir = Server.MapPath("/app_data/images"); var path = Path.Combine(dir, filename+"."+ (extension!=null? extension:"jpg")); // var extension = filename.Substring(0,filename.LastIndexOf(".")); return base.File(path, "image/jpeg"); } } }