Ответ 1
Так как ваши ссылки похожи, вы не можете их разделить на уровне маршрутизации. Но вот хорошая новость: вы можете написать собственный обработчик маршрута и забыть о типичном анализе ссылок ASP.NET MVC.
Прежде всего, добавьте RouteHandler
в стандартную маршрутизацию:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Default", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new SlugRouteHandler();
Это позволяет вам работать с вашими URL-адресами по-разному, например:
public class SlugRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var url = requestContext.HttpContext.Request.Path.TrimStart('/');
if (!string.IsNullOrEmpty(url))
{
PageItem page = RedirectManager.GetPageByFriendlyUrl(url);
if (page != null)
{
FillRequest(page.ControllerName,
page.ActionName ?? "GetStatic",
page.ID.ToString(),
requestContext);
}
}
return base.GetHttpHandler(requestContext);
}
private static void FillRequest(string controller, string action, string id, RequestContext requestContext)
{
if (requestContext == null)
{
throw new ArgumentNullException("requestContext");
}
requestContext.RouteData.Values["controller"] = controller;
requestContext.RouteData.Values["action"] = action;
requestContext.RouteData.Values["id"] = id;
}
}
Здесь требуются некоторые объяснения.
Прежде всего, ваш обработчик должен получить MvcRouteHandler
из System.Web.Mvc
.
PageItem
представляет мою DB-структуру, которая содержит всю необходимую информацию о slug:
ContentID
является внешним ключом к таблице содержимого.
GetStatic
- значение по умолчанию для действия, это было удобно в моем случае.
RedirectManager
- это статический класс, который работает с базой данных:
public static class RedirectManager
{
public static PageItem GetPageByFriendlyUrl(string friendlyUrl)
{
PageItem page = null;
using (var cmd = new SqlCommand())
{
cmd.Connection = new SqlConnection(/*YourConnectionString*/);
cmd.CommandText = "select * from FriendlyUrl where FriendlyUrl = @FriendlyUrl";
cmd.Parameters.Add("@FriendlyUrl", SqlDbType.NVarChar).Value = friendlyUrl.TrimEnd('/');
cmd.Connection.Open();
using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.Read())
{
page = new PageItem
{
ID = (int) reader["Id"],
ControllerName = (string) reader["ControllerName"],
ActionName = (string) reader["ActionName"],
FriendlyUrl = (string) reader["FriendlyUrl"],
};
}
}
return page;
}
}
}
Используя эту кодовую базу, вы можете добавить все ограничения, исключения и странное поведение.
Это сработало в моем случае. Надеюсь, это поможет вам.