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