Pontos em URL causa 404 com mvc do ASP.NET e IIS

Eu tenho um projeto que requer que meus URLs tenham pontos no caminho. Por exemplo, posso ter um URL como www.example.com/people/michael.phelps

URLs com o ponto geram um 404. Meu roteamento está bem. Se eu passar em michaelphelps, sem o ponto, então tudo funciona. Se eu adicionar o ponto, recebo um erro 404. O site de amostra está sendo executado no Windows 7 com o IIS8 Express. O URLScan não está em execução.

Eu tentei adicionar o seguinte ao meu web.config:

   

Infelizmente isso não fez diferença. Acabei de receber um erro 404.0 Not Found.

Este é um projeto do MVC4, mas não acho que seja relevante. Meu roteamento funciona bem e os parâmetros que espero estão lá, até incluírem um ponto.

O que preciso configurar para poder ter pontos no meu URL?

Eu tenho este trabalho editando manipuladores HTTP do meu site. Para minhas necessidades, isso funciona bem e resolve meu problema.

Eu simplesmente adicionei um novo manipulador HTTP que procura por critérios específicos de caminho. Se a solicitação corresponder, ela será enviada corretamente para o .NET para processamento. Estou muito mais feliz com esta solução que o URLRewrite hackou ou habilitou o RAMMFAR.

Por exemplo, para que o .NET processe o URL http://www.example.com/people/michael.phelps, adicione a seguinte linha ao web.config do seu site dentro do elemento system.webServer / handlers :

  

Editar

Há outros posts sugerindo que a solução para esse problema é RAMMFAR ou RunAllManagedModulesForAllRequests . Ativar esta opção ativará todos os módulos gerenciados para todas as solicitações. Isso significa que arquivos estáticos, como imagens, PDFs e tudo o mais, serão processados ​​pelo .NET quando não precisarem ser. Essa opção é melhor deixada a menos que você tenha um caso específico para ela.

Depois de alguns bisbilhotando descobri que relaxedUrlToFileSystemMapping não funcionava para mim, o que funcionou no meu caso foi configurar o RAMMFAR como true, o mesmo vale para (.net 4.0 + mvc3) e (.net 4.5 + mvc4).

   

Esteja ciente ao configurar o RAMMFAR verdadeiro post de Hanselman sobre RAMMFAR e desempenho

Eu acredito que você tem que definir a propriedade relaxedUrlToFileSystemMapping no seu web.config. Haack escreveu um artigo sobre isso há pouco tempo (e há alguns outros posts de SO fazendo o mesmo tipo de pergunta)

   

Basta adicionar esta seção ao Web.config e todas as solicitações para a rota / {* pathInfo} serão tratadas pelo manipulador especificado, mesmo quando houver pontos em pathInfo. (retirado do exemplo do ServiceStack MVC Host Web.config e desta resposta https://stackoverflow.com/a/12151501/801189 )

Isso deve funcionar para o IIS 6 e 7. Você pode atribuir manipuladores específicos a diferentes caminhos após a ‘rota’, modificando caminho = “*” em elementos ‘adicionar’

                 

Fiquei preso nessa questão por um longo tempo seguindo todos os remédios diferentes sem sucesso.

Notei que ao adicionar uma barra [/] ao final do URL contendo os pontos [.], Ele não causou um erro 404 e realmente funcionou.

Eu finalmente resolvi o problema usando um regravador de URL como o URL do IIS Reescreva para observar um determinado padrão e acrescentar a barra de treinamento.

Minha URL é assim: /Contato / ~ primeiro nome.Últimanome, então meu padrão é simplesmente: /Contato/~(.*[^/])$

Eu tenho essa idéia de Scott Forsyth, veja o link abaixo: http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path

Solução alternativa do MVC 5.0.

Muitas das respostas sugeridas parecem não funcionar no MVC 5.0.

Como o problema dos 404 pontos na última seção pode ser resolvido fechando essa seção com uma barra final, aqui está o pequeno truque que eu uso, limpo e simples.

Mantendo um espaço reservado conveniente na sua opinião:

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

adicione um pouco de jquery / javascript para fazer o trabalho:

  

por favor, note a barra final, que é responsável por mudar

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

para dentro

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

Resposta super fácil para aqueles que só têm isso em uma página da web. Edite seu link de ação e um + “/” no final dele.

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

Você pode querer pensar em usar travessões em vez de períodos.

No Pro ASP MVC 3 Framework, eles sugerem isso sobre fazer URLs amigáveis:

Evite símbolos, códigos e seqüências de caracteres. Se você quiser um separador de palavras, use um traço (/ my-great-article). Os sublinhados não são amigáveis ​​e os espaços codificados por URL são bizarros (/ my + great + article) ou repugnantes (/ my% 20great% 20article).

Também menciona que URLs devem ser fáceis de ler e mudar para humanos. Talvez um motivo para pensar em usar um traço em vez de um ponto também venha do mesmo livro:

Não use extensões de nome de arquivo para páginas HTML (.aspx ou .mvc), mas use-as para tipos de arquivos especializados (.jpg, .pdf, .zip, etc). Os navegadores da Web não se importam com extensões de nome de arquivo se você definir o tipo MIME adequadamente, mas os humanos ainda esperam que os arquivos PDF terminem com .pdf

Assim, enquanto um período ainda é legível para os seres humanos (embora menos legível do que traços, IMO), ainda pode ser um pouco confuso / enganoso, dependendo do que vem após o período. E se alguém tiver um sobrenome de zip? Em seguida, o URL será /John.zip em vez de / John-zip, algo que pode ser enganoso até mesmo para o desenvolvedor que escreveu o aplicativo.

Seria possível alterar sua estrutura de URL?
Para o que eu estava trabalhando eu tentei uma rota para

 url: "Download/{fileName}" 

mas falhou com qualquer coisa que tivesse um. nisso.

Mudei a rota para

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

Agora eu posso colocar no localhost:xxxxx/File1.doc/Download e funciona bem.

Meus ajudantes na visão também pegaram

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

que faz um link para o localhost:xxxxx/File1.doc/Download formato também.

Talvez você possa colocar uma palavra desnecessária como “/ view” ou ação no final de sua rota para que sua propriedade termine com um / algo como /mike.smith/view

Tentei todas as soluções acima, mas nenhum deles funcionou para mim. O que funcionou foi desinstalar as versões .NET> 4.5, incluindo todas as suas versões multilíngües; Por fim, acrescentei versões mais recentes (somente em inglês), peça por peça. Agora versões instaladas no meu sistema é isso:

  • 2,0
  • 3,0
  • 3,5 4
  • 4,5
  • 4.5.1
  • 4.5.2
  • 4,6
  • 4.6.1

E ainda está trabalhando neste momento. Eu tenho medo de instalar o 4.6.2 porque ele pode atrapalhar tudo.

Então, eu só poderia especular que ou 4.6.2 ou todas as versões não inglesas estavam bagunçando minha configuração.

HTH alguém.

Consegui resolver minha versão específica desse problema (tive que fazer /customer.html rota para / customer, barras não permitidas) usando a solução em https://stackoverflow.com/a/13082446/1454265 e substituindo o caminho = “*. html”.

Como solução poderia também considerar a codificação para um formato que não contém símbolo . como base64.

Em js deve ser adicionado

 btoa(parameter); 

No controlador

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

Adicionar regra de regravação de URL ao arquivo Web.config. Você precisa ter o módulo de regravação de URL já instalado no IIS. Use a seguinte regra de reescrita como inspiração para você.

                  

Além disso, (relacionado) verifique a ordem dos mapeamentos do manipulador. Nós tivemos um .ashx com um .svc (por exemplo, /foo.asmx/bar.svc/path) no caminho depois dele. O mapeamento .svc foi primeiro assim 404 para o caminho .svc que correspondeu antes do .asmx. Não pensei muito, mas talvez a url que codifica o caminho pudesse resolver isso.

Dependendo de como é importante manter seu URI sem querystrings, você também pode passar o valor com pontos como parte da querystring, não o URI.

Por exemplo, http://www.example.com/people?name=michael.phelps funcionará sem ter que alterar nenhuma configuração ou nada.

Você perde a elegância de ter um URI limpo, mas essa solução não requer alteração nem adição de configurações ou manipuladores.

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