0

I have my requirement to generate my URL as

/2013/10/custome-mvc-url-rout-to-display-mixture-of-id-and-urlslug

I have seen many questions to achieve it & my question may have possibility of Duplicate.. Like:-

asp-net-mvc-framework-part-2-url-routing

custome-mvc-url-rout-to-display-mixture-of-id-and-urlslug

etc...

I have achieved it as follows:-

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

and my Hyperlink which would generate this would be :-

@Html.ActionLink("continue...", "post", "blog", 
new { 
    year = Model.PostedOn.Year, 
    month = Model.PostedOn.Month, 
    day = Model.PostedOn.Day, 
    title = Model.UrlSlug 
}, new { title = "continue..." })

My MVC Controller being :-

public ViewResult Post(int year, int month, string title)
        {}

But the issue over here is , I am getting my URL as :

http://localhost:2083/blog/post?Year=2013&Month=10&Day=9&title=best_practices_in_programming

and not like :-

http://localhost:2083/blog/post/2013/10/best_practices_in_programming

What am I doing wrong ? Please can someone point it.

Thnks!

Community
  • 1
  • 1
Shubh
  • 6,693
  • 9
  • 48
  • 83
  • can you post your routes? specifically the order of the routes (Post and Default). i think the route should be `routes.MapRoute( "Post", "blog/post/{year}/{month}/{title}", new { controller = "Blog", action = "Post" } );`, otherwise the segments might conflict with the default route. – shakib Oct 09 '13 at 17:30

1 Answers1

0

I tried this and it worked as long as you put this route before the default route in RouteConfig.cs like this:

 routes.MapRoute(
                null,
                "{year}/{month}/{title}",
                new { controller = "Blog", action = "Post" },
                new {  year = @"\d+", month = @"\d+", title = @"[\w\-]*" });

You should also change the title to use hyphens instead of underscores IMO. Here is a good helper to do this.

  #region ToSlug(), AsMovedPermanently
    public static class PermanentRedirectionExtensions
    {
        public static PermanentRedirectToRouteResult AsMovedPermanently
            (this RedirectToRouteResult redirection)
        {
            return new PermanentRedirectToRouteResult(redirection);
        }
    }

    public class PermanentRedirectToRouteResult : ActionResult
    {
        public RedirectToRouteResult Redirection { get; private set; }
        public PermanentRedirectToRouteResult(RedirectToRouteResult redirection)
        {
            this.Redirection = redirection;
        }
        public override void ExecuteResult(ControllerContext context)
        {
            // After setting up a normal redirection, switch it to a 301
            Redirection.ExecuteResult(context);
            context.HttpContext.Response.StatusCode = 301;
            context.HttpContext.Response.Status = "301 Moved Permanently";
        }
    }



    public static class StringExtensions
    {
        private static readonly Encoding Encoding = Encoding.GetEncoding("Cyrillic");

        public static string RemoveAccent(this string value)
        {
            byte[] bytes = Encoding.GetBytes(value);
            return Encoding.ASCII.GetString(bytes);
        }



        public static string ToSlug(this string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                return string.Empty;
            }

            var str = value.RemoveAccent().ToLowerInvariant();

            str = Regex.Replace(str, @"[^a-z0-9\s-]", "");

            str = Regex.Replace(str, @"\s+", " ").Trim();

            str = str.Substring(0, str.Length <= 200 ? str.Length : 200).Trim();

            str = Regex.Replace(str, @"\s", "-");

            str = Regex.Replace(str, @"-+", "-");

            return str;
        }
    }
    #endregion

Then you would also have to have a helper that replaces each hyphen with a whitespace from the url parameter title that you will likely pass to the controller action Post to query for the Post in the DB.

yardpenalty.com
  • 1,244
  • 2
  • 17
  • 32