1

问:MVC URL路由,路由到错误的路由,为什么?

这是我的RegisterRoutes:

public static void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 


      routes.Add("ImagesRoute", new Route("graphics/{*filename}", new HttpRuntime.Routing.ImageRouteHandler())); 


      // insert_dateti 
      routes.MapRoute(
       "Default", // Routenname 
       "{controller}/{action}/{id}", // URL mit Parametern 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte 
       //new { controller = "Home", action = "Splash", id = UrlParameter.Optional } // Parameterstandardwerte 
       //new { controller = "Folders", action = "Content", id = UrlParameter.Optional } // Parameterstandardwerte 
      ); 



     } // End Sub RegisterRoutes 

这是我的路由处理

using System; 
using System.IO; 
using System.Web; 
using System.Linq; 
using System.Web.UI; 
using System.Web.Routing; 
using System.Web.Compilation; 
using System.Collections.Generic; 


namespace HttpRuntime.Routing 
{ 


    public class ImageRouteHandler : IRouteHandler 
    { 


     public string MapRemoteLocation(string strPath) 
     { 
      if (string.IsNullOrEmpty(strPath)) 
       return ""; 

      string strBaseURL = "http://madskristensen.net/themes/standard/"; 
      return strBaseURL + strPath; 
     } 

     public IHttpHandler GetHttpHandler(RequestContext requestContext) 
     { 


      string filename = requestContext.RouteData.Values["filename"] as string; 

      if (string.IsNullOrEmpty(filename)) 
      { 
       // return a 404 HttpHandler here 
       requestContext.HttpContext.Response.StatusCode = 404; 
       requestContext.HttpContext.Response.End(); 
       return null; 
      } // End if (string.IsNullOrEmpty(filename)) 
      else 
      { 
       requestContext.HttpContext.Response.Clear(); 
       requestContext.HttpContext.Response.ContentType = GetContentType(filename); 
       requestContext.HttpContext.Response.Redirect(MapRemoteLocation(filename)); 


       // find physical path to image here. 
       //string filepath = requestContext.HttpContext.Server.MapPath("~/test.jpg"); 


       // string stPath = requestContext.HttpContext.Request.Url.AbsolutePath; 
       //requestContext.HttpContext.Response.WriteFile(filepath); 
       //requestContext.HttpContext.Response.End(); 
      } // End Else of if (string.IsNullOrEmpty(filename)) 

      return null; 
     } // End Function GetHttpHandler 


     public static void MsgBox(object obj) 
     { 
      if (obj != null) 
       System.Windows.Forms.MessageBox.Show(obj.ToString()); 
      else 
       System.Windows.Forms.MessageBox.Show("obj is NULL"); 
     } // End Sub MsgBox 


     private static string GetContentType(String path) 
     { 
      switch (Path.GetExtension(path)) 
      { 
       case ".bmp": return "Image/bmp"; 
       case ".gif": return "Image/gif"; 
       case ".jpg": return "Image/jpeg"; 
       case ".png": return "Image/png"; 
       default: break; 
      } // End switch (Path.GetExtension(path)) 
      return ""; 
     } // End Function GetContentType 


    } // End Class ImageRouteHandler : IRouteHandler 


} // End Namespace HttpRuntime.Routing 

这样做的目的是,当我有这个在/ home /指数。 cshtml

<img src="graphics/mads2011.png?v=123" title="Compose E-Mail" alt="Compose E-Mail" /> 

它从远程主机下载图片。

它正常工作,只要我有

routes.Add("ImagesRoute", new Route("graphics/{filename}", new HttpRuntime.Routing.ImageRouteHandler())); 

但是,当我为了让子文件夹将其更改为

routes.Add("ImagesRoute", new Route("graphics/{*filename}", new HttpRuntime.Routing.ImageRouteHandler())); 

,然后重定向每个URL动作/图形。

例如当我在主页/ Index.cshtml有

$(function() { 
     $("#divJsTreeDemo").jstree({ 
     "json_data" : { 
      "ajax" : { 
       "url": "@Url.Action("GetNodesJson", "Home")" 
       //"url": "@Url.Action("GetTreeData", "Home")" 
       ,"async" : true 

为生成的HTML页面上的AJAX调用的URL变得

"url": "/graphics?action=GetNodesJson&amp;controller=Home" 

这是为什么? 我该如何解决这个问题? 如果我将我的ImagesRoute移动到底部,JavaScript正确路由,但是我不能获得更多的远程图像,因为它们被路由到控制器“图形”,它不存在 - > Exception no such view ...

+1

我绝对喜欢aspnetmvc ...我绝对讨厌路由。我感到你的痛苦。对不起,我无法帮忙。 – Jamiec

+0

哦,有一个可能的帮助是我在使用来自http://mvccontrib.codeplex.com/的路由调试器时遇到路由问题。 – Jamiec

回答

2

当建立从路线链接,您ImagesRoute使用{*filename}将满足所有条件,使路线将始终被用来建立联系,如果它先于你的路由表的Default路线。但是,处理请求时,它会按预期工作,因为ImagesRoute路由只能通过开始的请求来满足http://mysite.com/graphics/...

为了解决此问题,您需要将默认路由下面的ImagesRoutes移动,然后您需要添加将RouteConstraint设置为默认路由,以便以graphics开头的任何请求都将使默认路由失败。

更改默认路线如下:

routes.MapRoute(
    "Default", // Routenname 
    "{controller}/{action}/{id}", // URL mit Parametern 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults 
    new { controller = @"^(?!graphics).+" } // constraint 
); 
+0

太棒了,作品!非常感谢你 !虽然我必须说我仍然不明白为什么@ Url.Action(“GetNodesJson”,“Home”)“/ Home/GetNodesJson满足/ graphics/whatever。或者为什么@ Url.Action(”ActionName“,” ControllerName“)变成了图形/控制器名称/ ActionName。不知何故,它只是填充到route1的扩展route2 ...我想我必须阅读MVC的来源才能理解路由部分。 –

+0

因为你的ImagesRoute URL参数由单个贪婪匹配组成,它匹配由MVC构建的任何链接。在链接建设方面,一切都与该路线相匹配。请标记为已回答。谢谢。 – counsellorben