2011-11-03 3 views
2

J'utilise le routage via Global.asax.Problèmes de routage .NET 4

Je veux http://www.website.com/ad/123 conduire à http://www.website.com/ad.aspx?id=123

Cela fonctionne bien en utilisant:

routes.MapPageRoute("AdById", "ad/{cid}", "~/ad.aspx"); 

je devais "de-route" les js et les fichiers CSS et des images, donc j'ai quelques gestionnaires pour que:

routes.Add("AdImagesRoute", new Route("ad/graphics/{filename}.{ext}", new ImageRouteHandler())); 
routes.Add("AdJSRoute", new Route("ad/scripts/{filename}.js", new JSRouteHandler())); 
routes.Add("AdCSSRoute", new Route("ad/styles/{filename}.css", new CSSRouteHandler())); 

maintenant, je veux aussi « décorer » l'URL, donc je veux quelque chose comme ceci:

http://www.website.com/ad/123/House%20For%20Sale

également conduire à http://www.website.com/ad.aspx?id=123

donc j'ajouté celui-ci:

routes.MapPageRoute("AdByIdWithBlah", "ad/{cid}/{blah}", "~/ad.aspx"); 

Mais le problème est que lorsque le client va à l'adresse suivante: http://www.website.com/ad/123, les javascripts sont invités comme http://www.website.com/ad/scripts/scriptfile.js ce qui fait que le routage pense qu'il s'agit d'un numéro d'annonce et d'un 'blah' et redirige vers ad.aspx.

Je dois donc dire au Routage que si cid n'est pas un nombre (parce que c'est un dossier) ou blah se termine par .js ou .css alors ne pas router.

J'ai essayé ceci:

Route adwithblahroute = new Route("ad/{cid}/{blah}", new RouteValueDictionary() {{"blah", "blah"}} , new RouteValueDictionary() { { "cid", @"^\d+$" }, {"blah", @"^[^.]$"} }, new BlahRouteHandler()); 
routes.Add(adwithblahroute); 

Mais maintenant, je reçois un 404 si je demande http://www.website.com/ad/123/sometext

J'espère que quelqu'un peut me aider à résoudre ce problème.

---- ---- EDIT

BTW, Ceci est le BlahRouteHandler:

public class BlahRouteHandler : IRouteHandler 
    { 
     public IHttpHandler GetHttpHandler(RequestContext requestContext) 
     { 
      int cid = 0; 
      string filepath; 
      if (Int32.TryParse(requestContext.RouteData.Values["cid"] as string, out cid)) 
      { 
       filepath = requestContext.HttpContext.Server.MapPath("~/ad.aspx"); 
       requestContext.HttpContext.Response.WriteFile(filepath); 
       requestContext.HttpContext.Response.End(); 
      } 
      else 
      { 
       requestContext.HttpContext.Response.Clear(); 
       requestContext.HttpContext.Response.StatusCode = 404; 
       requestContext.HttpContext.Response.End(); 
      } 
      return null; 
     } 
    } 

------ ------ AJOUTÉE

Juste pour Google, j'ai trouvé une solution d'une ligne, je n'ai pas besoin du gestionnaire ou de la classe, comme il semble. Cette ligne a fait l'affaire:

routes.MapPageRoute("AdByIdWithBlah", "ad/{cid}/{blah}", "~/ad.aspx", false, new RouteValueDictionary() { { "blah", "blah" } }, new RouteValueDictionary() { { "cid", @"^\d+$" } }); 

Répondre

1

Créer une nouvelle classe d'itinéraire qui dérive Route et ne mettre en œuvre l'analyse de la route en elle (laissez la base gérer tout le reste). Ce faisant, vous pouvez vérifier si la deuxième partie du chemin est vraiment un nombre.

Ensuite, il suffit de l'ajouter comme le premier itinéraire dans le dictionnaire.

public class MyCustomRoute : Route 
{ 
    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var url = httpContext.Request.ApplicationPath.TrimEnd('/'); 
     var relativeUri = httpContext.Request.Url.AbsolutePath.Remove(0, url.Length); 

     // split url here 
     // return null if the second path part is not a number 
     // else invoke base.GetRouteData 
     return null; 
    } 
} 
+0

Je pense que je vais avoir besoin d'un peu plus d'aide pour l'implémenter. J'ai essayé d'ajouter la classe à Global.asax, en divisant le relatifUri et tout, comme vous le suggérez, mais je ne sais pas comment l'ajouter. 'routes.Add (new AdBlahRoute (" ad/{cid}/{blah} ", nouveau BlahRouteHandler()));' Mais cela ne fonctionne pas, car "'System.Web.Routing.Route' ne contient pas un constructeur qui prend 0 arguments "et" 'ASP.global_asax.AdBlahRoute » ne contient pas de constructeur qui prend 2 arguments » – Jesper

+0

Tous les itinéraires doivent être nommés (premier argument) – jgauffin

+0

Est-ce correct ?: 'public class AdBlahRoute: Route { public override RouteData GetRouteData (HttpContextBase HttpContext) {var url = httpContext.Request.ApplicationPath.TrimEnd ('/'); var relativeUri = httpContext.Request.Url.AbsolutePath.Remove (0, url.Length); chaîne [] urlparts = relativeUri.Split ('/') ; essayer { Convert.ToInt32 (urlparts [1]); retour base.GetRouteData (HttpContext);} prises { return null; } } } ' – Jesper