URL中的点导致404与ASP.NET mvc和IIS
我有一个项目,要求我的url在path中有点。 例如,我可能有一个URL,如www.example.com/people/michael.phelps
带点的URL生成一个404.我的路由很好。 如果我通过michaelphelps,没有点,那么一切正常。 如果我添加点,我得到一个404错误。 示例站点使用IIS8 Express在Windows 7上运行。 URLScan未运行。
我尝试添加以下到我的web.config:
<security> <requestFiltering allowDoubleEscaping="true"/> </security>
不幸的是,这没有什么区别。 我刚刚收到一个404.0未find错误。
这是一个MVC4项目,但我不认为这是相关的。 我的路由工作正常,我期望的参数在那里,直到他们包括一个点。
我需要什么configuration,所以我可以在我的url有点?
我通过编辑我的网站的HTTP处理程序得到了这个工作。 为了我的需要,这个工作很好,解决了我的问题。
我只是添加了一个新的HTTP处理程序,查找特定的path标准。 如果请求匹配,则将其正确发送给.NET进行处理。 这个解决scheme让URLRewrite破解或启用RAMMFAR,我感到非常开心。
例如,要让.NET处理URL http://www.example.com/people/michael.phelps,;请将以下行添加到system.webServer / handlers
元素内的网站web.config中:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="/people/*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
编辑
还有其他post提示这个问题的解决scheme是RAMMFAR
或RunAllManagedModulesForAllRequests
。 启用此选项将启用所有请求的托pipe模块。 这意味着静态文件,如图像,PDF文件和其他一切将被.NET处理,当他们不需要。 除非你有特定的情况,否则这个选项是最好的。
经过一番周折之后,我发现relaxedUrlToFileSystemMapping对我来说根本不起作用,在我的情况下,RAMMFAR设置为true,对(.net 4.0 + mvc3)和(.net 4.5 + mvc4)同样有效。
<system.webserver> <modules runAllManagedModulesForAllRequests="true">
当设置RAMMFAR真正的Hanselman关于RAMMFAR和性能时,请注意
我相信你必须在你的web.config中设置属性relaxedUrlToFileSystemMapping。 哈克在前一段时间写了一篇文章(还有一些其他的SOpost提出了相同types的问题)
<system.web> <httpRuntime relaxedUrlToFileSystemMapping="true" />
只需将此部分添加到Web.config中,即使path信息中有点,所有对路由/ {* pathInfo}的请求都将由指定的处理程序处理。 (取自ServiceStack MVC主机Web.config示例和此答案https://stackoverflow.com/a/12151501/801189 )
这应该适用于IIS 6和7.您可以在“路由”之后通过修改“add”元素中的path =“*”,将特定的处理程序分配到不同的path
<location path="route"> <system.web> <httpHandlers> <add path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" /> </httpHandlers> </system.web> <!-- Required for IIS 7.0 --> <system.webServer> <modules runAllManagedModulesForAllRequests="true" /> <validation validateIntegratedModeConfiguration="false" /> <handlers> <add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> </location>
很长时间以来,我一直在这个问题上停滞不前,无济于事。
我注意到,当向包含点[。]的URL的末尾添加正斜杠[/]时,它没有抛出404错误,并且它实际上工作。
我终于解决了这个问题,使用URL重写器,如IIS URL重写,以观察特定的模式,并追加训练斜线。
我的URL看起来像这样:/Contact/~firstname.lastname所以我的模式很简单:/Contact/~(.*[^/])$
我从Scott Forsyth那里得到了这个想法,请看下面的链接: http : //weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path
你可能想考虑使用破折号而不是句点。
在Pro ASP MVC 3框架中,他们build议使用友好的URL:
避免符号,代码和字符序列。 如果你想要一个词分隔符,使用破折号(/我的伟大的文章)。 下划线是不友好的,URL编码的空格是怪异的(/我的+伟大+文章)或恶心(/我%20great%20article)。
它还提到URL应该易于阅读和改变人类。 也许有一个理由来考虑使用破折号而不是一个点也来自同一本书:
不要使用HTML页面(.aspx或.mvc)的文件扩展名,而是将它们用于特定的文件types(.jpg,.pdf,.zip等)。 如果您正确设置MIMEtypes,Web浏览器不关心文件扩展名,但人们仍然期望PDF文件以.pdf
所以,虽然人类仍然可以读懂一段时间(尽pipe可读性不如破折号,海事组织),但可能仍然有点混淆/误导,取决于这段时间之后会发生什么。 如果某人有一个zip的姓氏怎么办? 那么这个URL将会是/John.zip而不是/ John-zip,甚至会让开发人员误以为是应用程序。
超级简单的答案,只有在一个网页上有这个。 编辑你的动作链接和一个+“/”的结尾。
@Html.ActionLink("Edit", "Edit", new { id = item.name + "/" }) |
MVC 5.0解决方法。
许多build议的答案似乎不适用于MVC 5.0。
由于在最后一节中的404点问题可以通过用斜线closures该部分来解决,下面是我使用的小技巧,干净而简单。
在您的视图中保留一个方便的占位符:
@Html.ActionLink("Change your Town", "Manage", "GeoData", new { id = User.Identity.Name }, null)
添加一点jquery / JavaScript来完成这项工作:
<script> $('a:contains("Change your Town")').on("click", function (event) { event.preventDefault(); window.location.href = '@Url.Action("Manage", "GeoData", new { id = User.Identity.Name })' + "/"; });</script>
请注意尾部的斜线,即负责更改
http://localhost:51003/GeoData/Manage/user@foo.com
成
http://localhost:51003/GeoData/Manage/user@foo.com/
有可能改变你的url结构吗?
对于我正在做的工作,我尝试了一条路线
url: "Download/{fileName}"
但它没有任何有一个。 在里面。
我切换路线
routes.MapRoute( name: "Download", url: "{fileName}/Download", defaults: new { controller = "Home", action = "Download", } );
现在我可以把localhost:xxxxx/File1.doc/Download
,它工作正常。
我的帮助者也认识到了这一点
@Html.ActionLink("click here", "Download", new { fileName = "File1.doc"})
它localhost:xxxxx/File1.doc/Download
链接到localhost:xxxxx/File1.doc/Download
格式。
也许你可以在你的路线的末尾放一个不需要的词,如“/ view”或动作,这样你的财产就可以结尾了/
像/mike.smith/view
试过以上所有的解决scheme,但没有一个为我工作。 什么工作是我卸载.NET版本> 4.5,包括其所有的多语言版本; 最后,我逐个添加了更新的(仅英文版本)版本。 现在安装在我的系统上的版本是这样的:
- 2.0
- 3.0
- 3.5 4
- 4.5
- 4.5.1
- 4.5.2
- 4.6
- 4.6.1
而且至今仍在工作。 我害怕安装4.6.2,因为它可能会搞砸一切。
所以我只能推测,4.6.2或所有这些非英文版本都搞乱了我的configuration。
HTH的人。
我能够解决我的这个问题的特定版本(必须使/customer.html路由到/客户,尾随斜杠不允许)使用解决scheme在https://stackoverflow.com/a/13082446/1454265 ,并代之以path= “* HTML”。
由于解决scheme也可以考虑编码为不包含符号的格式.
,作为base64。
在JS应该被添加
btoa(parameter);
在控制器中
byte[] bytes = Convert.FromBase64String(parameter); string parameter= Encoding.UTF8.GetString(bytes);
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"); } } }