Pretty URL ASP.NET MVC

前端 未结 3 1098
不知归路
不知归路 2020-12-29 00:45

How can I get pretty urls like localhost:8888/News/Example-post instead of localhost:8888/Home/Details/2

My HomeController has the following for the Details method

相关标签:
3条回答
  • 2020-12-29 01:20

    What I do on my sites is that I check the URL against either the Page Title or Page Stub in cases where the page titles could have the same name for instance if you have a site that posts a "Picture of the Week" you may want to use a stub instead of title as you'll have multiples named the same thing.

    URLs look like this: http://mySite.com/Page/Verse-of-the-Week

    Global.asax contains this:

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

    PageController is this:

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

    The repository looks like this:

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

    I hope that helps.

    Edit to add duplicate handling:

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

    Validates like this:

            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 讨论(0)
  • 2020-12-29 01:24

    As the ASP.NET routing system is somewhat complicated, there are many ways to accomplish what you describe.

    First of all, do you just want to have a pretty URL for the Details method? If so, you might consider renaming HomeController to NewsController or moving the Details method into a new NewsController class - that will automatically form the /News part of the URL. If you don't want a /Details part, you might rename your Details method Index, as that will be automatically called by /News. Finally, you need to change your int id parameter into string name.

    If you want many custom URLs, you're going to have to define your own routes. Here are two ways of doing this:

    1. The easiest way I've found is to use an ASP.NET MVC Attribute-Based Route Mapper. That way, all you have to do is add an attribute on each method you want a pretty URL for and specify what URL you want.

    First, you must follow a few steps to set up the attribute-based route mapping system, as outlined on that link. After completing those steps, you must change your method to look like this:

    [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. Alternatively, you can define your custom routes manually in Global.asax.cs. In your RegisterRoutes method, you can add the following in the middle:

    routes.MapRoute(
                    "NewsDetails",                                                   
                    "News/{name}",                                 
                    new { controller = "News", action = "Details", name = "" }
                );
    
    0 讨论(0)
  • 2020-12-29 01:27

    Please check out this package I've created: https://www.nuget.org/packages/LowercaseDashedRoute/ And read the one-line configuration here: https://github.com/AtaS/lowercase-dashed-route

    0 讨论(0)
提交回复
热议问题