Как реализовать переписывание URL аналогично SO

Мне нужно реализовать SO как функциональность на моем сайте MVC asp.net.

Например, когда пользователь переходит к https://stackoverflow.com/info/xxxxxxxx

после загрузки строка темы конкатенируется с url, и url становится следующим образом https://stackoverflow.com/info/xxxxxxxx/rails-sql-search-through-has-one-relationship

В URL добавлена ​​часть "/rails-sql-search-through-has-one-relationship".

В webforms это просто, я мог бы просто использовать переписывание URL. Но не уверен, как это сделать в MVC

Следующая строка из файла Global.asax

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Account", action = "LogOn", id = UrlParameter.Optional } // Parameter defaults
        );

строка, которая мне нужна для конкатенации, находится в моей базе данных, поэтому она извлекается оттуда. Как я могу это сделать?

Ответ 1

Это называется маршрутом пули. Один из способов достижения этого - определить маршрут с необязательным параметром slug, а в методе контроллера проверить, предоставлен ли параметр

routes.MapRoute(
    name: "Question",
    url: "Question/{id}/{slug}",
    defaults: new { controller = "Question", action = "Details", slug = UrlParameter.Optional }
);

Затем в QuestionController (предполагается, что id всегда будет предоставлен)

public ActionResult Details (int id, string slug)
{
    if (string.IsNullOrEmpty(slug))
    {
        // Look up the slug in the database based on the id, but for testing
        slug = "this-is-a-slug";
        return RedirectToAction("Details", new { id = id, slug = slug });
    }
    var model = db.Questions.Find(id);
    return View(model);
}

Ответ 2

Вы ищете собственный маршрут. Если вы внимательно посмотрите, SO не заботится о текстовой части URL-адреса. Итак:

 http://stackoverflow.com/info/xxxxxxxx/rails-sql-search-through-has-one-relationship
 AND
 http://stackoverflow.com/info/xxxxxxxx/

Оба будут работать. Вы можете легко сделать это с помощью чего-то вроде:

routes.MapRoute(
    "Question",
    "questions/{id}/{title}",
    new { controller = "Question", action = "Details" });

Трюк добавляет "slug" в конце при создании ссылок:

@Html.RouteLink(
    "Read more.",
    "Question",
    new { id = question.Id, title = Slugger.ToUrl(question.Title) })