0

こんにちは私はかなり長い間、ルーティングとリンクに関連する問題を解決しようとしてきましたが、うまくいきませんでした。

多数の本を保存するアプリケーションがあります。各本には、その詳細を表示するリンクがあります。詳細を取得するために、リンク内の各書籍の ID を使用しています。これはリンクのコードです:

@Html.ActionLink(book.Name, "Details", new { bookId = book.Id , book = book.BookUrl })

ユーザーがリンクの 1 つをクリックすると、これが呼び出されているコントローラーであり、変更することはできません。

 public ActionResult Details (int bookId){..}

そして、これは私のリンクがどのように表示されるかです:

http://localhost:51208/Home/Details/C-sharp-5.0-in-a-Nutshell-The-Definitive-Reference/BookId-2

私が望むのは、コントローラ アクションと BookId の表示を何らかの形で停止することです。したがって、私のリンクは次のようになります。

http://localhost:51208/C-sharp-5.0-in-a-Nutshell-The-Definitive-Reference

これまでのところ、ルーティングの標準機能を使用してこれを行う方法はないため、何らかの方法で機能を拡張する必要があると考えました。

私はPRO ASP.NET MVC 4でこれについて読んでおり、読んだことから、クラスを作成してから継承する必要がありますRouteBase

これにより、1 つともう 1 つの 2 つのメソッドを実装する必要がRouteData GetRouteData(HttpContextBase httpContext)あります。VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)

これまでのところ、リンクを生成する責任があることしか理解していGetVirtualPathないので、必要な機能を得るために実装を作成する必要があると思います。

この場合、誰かがこのメソッドをどのように実装する必要があるかについて私にアイデアを与えることができますか?

これが取るべきルートでない場合、どうすれば私が望むものを達成できますか?

4

2 に答える 2

1

独自のバージョンの RouteBase を実装することで、これを行うことができます。と の両方を実装する必要がありGetRouteDataますGetVirtualPath

の実装でGetRouteDataは、本のデータベースをチェックして、URL にデータベース内の本の名前が含まれているかどうかを確認し、正しいルート データを返す必要があります。

public class BookRoute : RouteBase
{
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var url = httpContext.Request.AppRelativeCurrentExecutionFilePath;
        url = url.Replace(@"~/", "");

        var book = getBookWithTheNameThatMatchesTheUrl(url);

        if (book != null)
        {
            var rd = new RouteData(this, new MvcRouteHandler());
            rd.Values.Add("controller", "Home");
            rd.Values.Add("action", "Details");
            rd.Values.Add("bookId", book.Id);
            return rd;
        }

        return null;
    }

の実装でGetVirtualPathは逆のことを行う必要があります。指定された ID を持つ本の名前を見つけて、適切な URL を返します。

例えば

public override VirtualPathData GetVirtualPath(RequestContext requestContext, 
                                               RouteValueDictionary values)
{
    if ((string)values["action"] == "Details" && 
        (string)values["controller"] == "Home")
    {
        var bookId = (int)values["bookId"];
        var bookName = LookUpTheBookNameForTheBookWithThisId(bookId);
        return new VirtualPathData(this, bookName);    
    }

    return null;
}

最後に、routes.Add(new BookRoute());ルートを登録する場所を追加して、この新しいルートを確認できるようにします。

メソッドgetBookWithTheNameThatMatchesTheUrl()がすべてのページでデータベースにヒットすることを考えると、ルックアップをキャッシュする必要があります。

于 2013-03-14T03:42:26.793 に答える