2011-01-06 13 views
1

Wie kann ich ziemlich Urls wie localhost erhalten: 8888/News/Beispiel-post statt localhost: 8888/Home/Details/2Recht URL ASP.NET MVC

My Homecontroller hat folgende für die Details der Methode

public ActionResult Details(int id) 
{ 
    var ArticleToView = (from m in _db.ArticleSet where m.storyId == id select m).First(); 

    return View(ArticleToView); 

Antwort

9

Da das ASP.NET-Routing-System etwas kompliziert ist, gibt es viele Möglichkeiten, um das zu erreichen, was Sie beschreiben.

Zunächst einmal wollen Sie einfach nur eine hübsche URL für die Details der Methode haben? Wenn ja, könnten Sie Homecontroller zu Newscontroller oder Bewegen der Details der Verfahren in eine neue Klasse Newscontroller Umbenennung - die automatisch die /News Teil der URL bilden. Wenn Sie nicht über einen /Details Teil mögen, können Sie Ihre Details der Methode Index, umbenennen, dass automatisch von /News aufgerufen werden. Schließlich müssen Sie Ihre int id Parameter in string name ändern.

Wenn Sie viele benutzerdefinierte URLs wollen, dann werden Sie Ihre eigenen Routen definieren müssen. Hier sind zwei Möglichkeiten, dies zu tun:

1. Der einfachste Weg, die ich gefunden habe ist verwenden, um eine ASP.NET MVC Attribute-Based Route Mapper. Auf diese Weise müssen Sie lediglich ein Attribut für jede Methode hinzufügen, für die Sie eine schöne URL erhalten möchten, und die gewünschte URL angeben.

Zuerst müssen Sie ein paar Schritte ausführen, um das attributbasierte Routen-Mapping-System einzurichten, wie in diesem Link beschrieben. Nachdem diese Schritte abgeschlossen haben, müssen Sie Ihre Methode wie folgt aussehen ändern:

[Url("News/{name}")] 
public ActionResult Details(string name) 
{ 
    var ArticleToView = (from m in _db.ArticleSet where m.storyName == name select m).First(); 

    return View(ArticleToView); 
} 

2. Alternativ können Sie Ihre eigene Routen manuell in Global.asax.cs definieren. In Ihrem RegisterRoutes Methode können Sie die folgenden in der Mitte hinzu:

routes.MapRoute(
       "NewsDetails",             
       "News/{name}",         
       new { controller = "News", action = "Details", name = "" } 
      ); 
+0

Gibt es keine eingebaute Möglichkeit, dies ohne zusätzliche Add-ons etc. zu tun? – Cameron

+0

@Cameron Sicher gibt es: y Sie können Routen in Global.asax genauso einfach definieren, aber ich habe festgestellt, dass die Verwendung von etwas wie dem, mit dem ich verlinkt habe, die zusätzliche DLL definitiv wert ist. –

+0

Wie wäre es, wenn Sie Home to News für alle Methoden des HomeControllers ändern würden? – Cameron

1

Was ich auf meinen Seiten ist, dass ich die URL entweder gegen die Seitentitel oder Seite Stub in Fällen überprüfen, in denen die Seitentitel die haben könnte gleichen Namen zum Beispiel, wenn Sie eine Website, die ein „Bild der Woche“ postet man einen Stub statt Titel verwenden möchten, wie Sie die Multiples gleiche Sache benannt haben werden.

URLs wie folgt aussehen: http://mySite.com/Page/Verse-of-the-Week

Global.asax enthält diese:

routes.MapRoute("Pages", "{controller}/{pageID}", new { controller = "Page", action = "Index", pageID = "Home" }); 

Pagecontroller ist dies:

[AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult Index(string pageID) 
    { 
     if (pageID == null) 
     { 
      pageID = pageRepository.HomeOrLowest(); 
     } 
     var p = pageRepository.ByStub(pageID); 
     if (p == null) { return RedirectToAction("NotFound", "Error"); } 
     return View(p); 
    } 

Das Repository sieht wie folgt aus:

private static Func<mvCmsContext, string, Page> _byStub = 
     CompiledQuery.Compile((mvCmsContext context, string pageTitle) => 
      (from p in context.Pages 
      where p.pageTitle.Replace(" ", "-") == pageTitle 
      select p).SingleOrDefault()); 
    public Page ByStub(string pageTitle) 
    { 
     return _byStub(context, pageTitle); 
    } 

Ich hoffe das hilft.

bearbeiten doppelte Handhabung hinzuzufügen:

private static Func<mvCmsContext, string, int> _pageExists = 
     CompiledQuery.Compile((mvCmsContext context, string pageTitle) => 
      (from p in context.Pages 
      where p.pageTitle.Replace(" ", "-") == pageTitle 
      select p).Count()); 
    public bool PageExists(string pageTitle) 
    { 
     return Convert.ToBoolean(_pageExists(context, pageTitle)); 
    } 

wie dieser Test prüft:

 IValidationErrors errors = new ValidationErrors(); 
     if (CreateOrEdit == "Create") 
     { 
      if (pageRepository.PageExists(model.pageTitle) && !String.IsNullOrEmpty(model.pageTitle)) 
       errors.Add("pageTitle", "A page with this title already exists. Please edit it and try again."); 
     } 
+0

markieren - können Sie ein wenig mehr im Detail erläutern, wie Sie doppelte Seitennamen bitte abmildern. Ich bekomme den Kern dessen, was Sie sagen, aber mir ist nicht klar, wie Sie das Vorkommen von Duplikaten vollständig entfernen (hängen Sie die Seiten-ID an?). Danke .. –

+0

Es hängt von der Seite ab. Auf meiner persönlichen Seite löst es ValidationErrors aus und fordert Sie auf, die Seite umzubenennen. Sie können ebenso einfach eine Zahl oder eine DateTime anhängen (oder voranstellen), dann erneut durchlaufen und bei Bedarf inkrementieren. Bearbeiteter Beitrag, um die Überprüfung von PageExists zu berücksichtigen. – mark123