1

How can I remove the ID from the url in this situation below where I am loading records from my database in which each record has an ID and a SEO slug name of the record. I have searched for this dozens of times but never seem to quite get a working answer.

mypictures.com/animal/cat-pictures/1
mypictures.com/animal/dog-pictures/2
mypictures.com/animal/bird-pictures/3

In this example I have a website that has different categories of animals. Each one of these exists in the database. The Cat category has Animal_Id = 1, the dog category has Animal_Id = 2 , Bird Category Animal_Id = 3 and so on.

I want to only show the slug of that category BUT NEVER THE ID. I am using SEO friendly urls so the answer would have to take that into account. I know that one way to maybe do it is to have unique slugs for each record but still I don't even know where to begin.

Below is what my code looks like so far that makes this work with the horrible id in the url:

AnimalController:

public ActionResult Details(int? id)
{
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        tblAnimal tblAnimal = db.tblAnimals.Find(id);            

        if (tblAnimal == null)
        {
            return HttpNotFound();
        }
                  
        return PartialView("_animalProdListPageLoad", tblAnimal);         
}

This is the cshtml view that calls the partial view _animalProdListPageLoad that loads a list of animal picture accessories once we have landed on the Animal category page. This uses the id that I am trying not to pass in the url. I added this part to the explanation to illustrate that I still need the id to load stuff that connects to the tblAnimalPictures via the Animal_Id. In this case AnimalAccessories is connected to the Animal_Id table, so I would still need the ID I just don't want it in the url if that makes sense.

@model mypictures.Models.tblAnimal

@{ Html.RenderAction("GetAnimalAccesories", "Animal", new { Animal_Id = Model.Animal_Id });
                                        
                                        @Html.HiddenFor(Model => Model.Animal_Id)

                                        ViewBag.Store_Id_Passed = Model.Animal_Id;
                                    }

Then in my RouteConfig I have the following to show the SEO friendly routes:

routes.Add("AnimalDetails", 
               new SeoFriendlyRoute2("animal/{slug}/{id}",
               new RouteValueDictionary(new { controller = "Animal", action = "Details" }),
               new MvcRouteHandler()));

Then I have a class that handles that SeoFriendlyRoute2 that looks like this:

public class SeoFriendlyRoute2 : System.Web.Routing.Route
{
    public SeoFriendlyRoute2(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler)
    {
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);

        if (routeData != null)
        {
            if (routeData.Values.ContainsKey("id"))
                routeData.Values["id"] = GetIdValue(routeData.Values["id"]);
        }

        return routeData;
    }

    private object GetIdValue(object id)
    {
        if (id != null)
        {
            string idValue = id.ToString();

            var regex = new Regex(@"^(?<id>\d+).*$");
            var match = regex.Match(idValue);

            if (match.Success)
            {
                return match.Groups["id"].Value;
            }
        }

        return id;
    }
    
    private object GetslugValue(object slug)
    {
        if (slug != null)
        {
            string slugValue = slug.ToString();

            var regex = new Regex(@"^(?<id>\d+).*$");
            var match = regex.Match(slugValue);

            if (match.Success)
            {
                return match.Groups["id"].Value;
            }
        }

        return slug;
    }
}

Then in the tblAnimal model I have this, which is what generates the seo url slug:

public string GenerateSlug2()
    {            

        string phrase2 = string.Format("{0}-{1}", Animal_Id, slug);                        

        string str2 = RemoveAccent2(phrase2).ToLower();
        // invalid chars           
        str2 = Regex.Replace(str2, @"[^a-z0-9\s-]", "");
        // convert multiple spaces into one space   
        str2 = Regex.Replace(str2, @"\s+", " ").Trim();
        // cut and trim 
        str2 = str2.Substring(0, str2.Length <= 45 ? str2.Length : 45).Trim();
        str2 = Regex.Replace(str2, @"\s", "-"); // hyphens   
        return str2;
    }

    private string RemoveAccent2(string text)
    {
        byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(text);
        return System.Text.Encoding.ASCII.GetString(bytes);
    }

Then finally when run the application and navigate to the animal category for any of the records like Dog it looks like this:

mypictures.com/animal/dog-pictures/2

but I REALLY need this instead:

mypictures.com/animal/dog-pictures

Please Help Me, I have been stuck on this for months and really need a solution.

I have already tried this and just get a 404: I removed the id from the route config since I thought that was a possible solution but its not.

routes.Add("AnimalDetails", new SeoFriendlyRoute2("animal/{slug}",
   new RouteValueDictionary(new { controller = "Animal", action = "Details" }),
    new MvcRouteHandler()));

1 Answer 1

0

edit your route config like this

routes.Add("AnimalDetails", new SeoFriendlyRoute2("animal/{slug}",
       new RouteValueDictionary(new { controller = "Animal", action = "Details" }),
        new MvcRouteHandler()));
Sign up to request clarification or add additional context in comments.

1 Comment

Does not work. That was the first thing I tried and it just returns a 404

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.