Нестандартный маршрут для написания дружественные URL в ASP.NET в MVC 3


Я пытаюсь построить дружественные url, как /должность/1/мой первый пост. Я начал с построения мои ссылки такой:

@Html.ActionLink(Model.BlogPost.Title, "Index", "Post", new
{
   id = Model.BlogPost.Id,
   title = Model.FriendlyUrl
}, 
new { })

которые были обработаны по этому маршруту:

routes.MapRoute(
   "Post", // Route name
   "posts/{id}/{title}", // URL with parameters
    new { controller = "Post", action = "Index" }, // Parameter defaults
    new { id = "^[0-9]+$" }
 );

Когда я создаю мой взгляд модель, я бы дал ему IUrlNiceName , которую он использовал, чтобы создать выход из FriendlyUrl:

public string FriendlyUrl
{
    get{ return UrlNiceName.ConvertToNiceName(BlogPost.Title); }
}

Тогда я чувствовал, что я не хочу управлять UrlNiceName-ки на регуляторе уровня, чтобы потом строить собственный маршрут, чтобы сделать это для меня:

public class NiceNameRoute : RouteBase
{
    private IUrlNiceNames UrlNiceNames { get; set; }
    private string UrlPrefix { get { return "post/"; } }

    public NiceNameRoute(IUrlNiceNames urlNiceNames)
    {
        UrlNiceNames = urlNiceNames;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;
        string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath;

        //match e.g. post/1 or post/1/my-first-post
        Regex regex = new Regex(UrlPrefix + "[0-9]+($|/)");

        if (regex.Match(requestedURL).Success)
        {
            //get the start of the post id
            int prefixPos = requestedURL.IndexOf(UrlPrefix, StringComparison.OrdinalIgnoreCase);
            int startIdPos = prefixPos + UrlPrefix.Length;

            //get the end of the post id
            int endIdPos = requestedURL.IndexOf("/", startIdPos, StringComparison.OrdinalIgnoreCase);
            endIdPos = endIdPos == -1 ? requestedURL.Length : endIdPos;

            //get post id
            string id = requestedURL.Substring(startIdPos, endIdPos - startIdPos);

            result = new RouteData(this, new MvcRouteHandler());
            result.Values.Add("controller", "Post");
            result.Values.Add("action", "Index");
            result.Values.Add("id", id);
        }

        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext,
        RouteValueDictionary values)
    {
        VirtualPathData result = null;

        if (values.ContainsKey("title")
            && Convert.ToString(values["action"]) == "Index"
            && Convert.ToString(values["controller"]) == "Post")
        {
            string niceName = UrlNiceNames.ConvertToNiceName(Convert.ToString(values["title"]));

            result = new VirtualPathData(this, UrlPrefix + Convert.ToString(values["id"]) + "/" + niceName);
        }
        return result;
    }
}

который я зарегистрировал такой:

routes.Add(new NiceNameRoute(new HyphenUrlNiceNames()));

и генерировать ссылки такой:

@Html.ActionLink(Model.BlogPost.Title, "Index", "Post", new
{
   id = Model.BlogPost.Id,
   title = Model.BlogPost.Title
}, 
new { })

Я сначала хотел взять трещину в этом, но теперь я хочу знать, как специалистам отрасли сделать это. Я за инженера? Существует ли более простой подход, который также элегантно? Существуют ли какие-либо проблемы с моего маршрута?



16795
10
задан 5 декабря 2011 в 05:12 Источник Поделиться
Комментарии
1 ответ

Лично я думаю, что ты более думал он. Почему бы просто не создать метод расширения строкой называется FriendlyString или PrepareForUrl, а затем использовать исходный маршрут

@Html.ActionLink(Model.BlogPost.Title, "Index", "Post", new
{
id = Model.BlogPost.Id,
title = Model.BlogPost.Title.FriendlyString()
}, null)

7
ответ дан 6 декабря 2011 в 04:12 Источник Поделиться