0

I have asp.net MVC 4 site which the articles url is : www.site.com/article/623/friendly-url-here

I wan't that if someone accessing an article without the friendly url, it will be completed without redirecting and accessing the database twice (which will make the page load slower).

now:

Entering www.site.com/article/623 -> enter to www.site.com/article/623

as I want it to be:

Entering www.site.com/article/623/the-article-nice-url

(Note the the-article-nice-url being added)

UPDATED:

Route as I use in RouteConfig:

// Articles
routes.MapRoute(
    name: "Articles",
    url: "articles/{articleId}/{friendlyUrl}",
    defaults: new { controller = "PageManagement", action = "ViewArticle", articleId = UrlParameter.Optional, friendlyUrl = UrlParameter.Optional }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Page metadata as I use to store the data with DbContext:

public class PageMetadata
{
    [Key]
    public int Id { get; set; }

    public string RepresentationString { get; set; }

    public DateTime CreationDate { get; set; }

    public DateTime LastUpdateDate { get; set; }

    public bool IsVisible { get; set; }

    public string Title { get; set; }

    public string Content { get; set; }

    public string Link { get; set; }
}
Aviran Cohen
  • 5,581
  • 4
  • 48
  • 75

3 Answers3

0

I eventually used "RedirectToRoute" while storing the data fetched from the DB in a session obeject.

Request Flow:

  1. Request with only id in the url.
  2. Fetch page content from the database.
  3. Save the fetched page in session object named with its id ("article-53" for example) and redirect to the right route.
  4. fetch the page data from the session object if exists and clean the session object.

    public ActionResult ViewArticle(int? articleId, string friendlyUrl) { if (articleId == null) { return RedirectToActionPermanent("Index", "Home"); }

            if (Session[string.Format("article-{0}", articleId)] != null)
            {
                PageMetadata desiredPage = (PageMetadata)Session[string.Format("article-{0}", articleId)];
                Session[string.Format("article-{0}", articleId)] = null;
                return View(desiredPage);
            }
    
            var page = context.PageMetadatas.FirstOrDefault(p => p.Id == articleId);
    
            if (page == null)
            {
                return RedirectToActionPermanent("Index", "Home");
            }
    
            if (friendlyUrl != null)
            {
                // Redirect to proper name
                if (friendlyUrl != page.RepresentationString)
                {
                    Session[string.Format("article-{0}", page.Id)] = page;
                    return RedirectToRoute("Articles", new { controller = "PageManagement", action = "ViewArticle", articleId = articleId, friendlyUrl = page.RepresentationString });
                }
                return View(page);
            }
            else
            {
                Session[string.Format("article-{0}", page.Id)] = page;
                return RedirectToRoute("Articles", new { controller = "PageManagement", action = "ViewArticle", articleId = articleId, friendlyUrl = page.RepresentationString });
            }
        }
    
Aviran Cohen
  • 5,581
  • 4
  • 48
  • 75
0

This answer is not solution to your problem, but a look from different perspective:

You can't modify address in browser without redirection.

You should be sure, that you expose to users only one version of link. Second will redirect and there is nothing wrong about it, specially when only one type is exposed.

Address of this question is good example. if you go to http://stackoverflow.com/questions/13671002, you'll be redirected to http://stackoverflow.com/questions/13671002/friendly-url-redirection.

To be sure only one copy is used by search engines, you should also place canoncal url:

<link rel="canonical" href="http://stackoverflow.com/questions/13671002/friendly-url-redirection">

SEO unfriendly address should newer be exposed in any form. If you won't expose it, you won't have double database query.

LukLed
  • 31,452
  • 17
  • 82
  • 107
0

You need to use Url rewriting to achieve this. There are various techniques you can choose, depending on the way you want to handle mapping the article Id to the friendly url. Check out this article for a summary of the options available: http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx

Paul Taylor
  • 5,651
  • 5
  • 44
  • 68