3

mvc のデータベースに保存されている URL に基づいて、カスタム ルーティング ロジックを追加しようとしています。(CMSのように)かなり基本的なことだと思いますが、実際にはどこにも到達していないように感じます。

基本的に、ユーザーは次のような URL を入力できます。

www.somesite.com/categorya/categoryb/categoryf/someitem
www.somesite.com/about/someinfo

データベースには、これらのアイテムがタイプ (通常のページまたは製品ページ) とともに保存されます。

これに応じて、実際に別の「アクション」メソッドをヒットしたい、つまり、上記のメソッドをヒットしたい:

PageController/Product
PageController/Normal

これらのアクションは、このページのコンテンツをロードし、同じビュー (製品ビューまたは通常のビュー) を表示します。

通常のルーティング方法を使用してもうまくいきません。

cata/producta
cata/catb/catc/catd/cate/catf/producta

今、私はここを見てきました:検索のための ASP.NET MVC カスタム ルーティング

これをベースとして使用しようとしていますが、InvokeActionMethod 呼び出し内でヒットしたいアクション メソッドを実際に「変更」するにはどうすればよいですか?

ところでMVC 3.0を使用しています。

ヘルプ/提案をありがとう

最終的解決:

Global.asax

routes.MapRoute(
                "Default",
                "{*path}",
                new { controller = "Page", action = "NotFound", path= "Home" }
            ).RouteHandler = new ApplicationRouteHandler();

ルート ハンドラ

public class ApplicationRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new ApplicationHandler(requestContext);
        }
    }

    public class ApplicationHandler : MvcHandler, IRequiresSessionState
    {
        public ApplicationHandler(RequestContext requestContext)
            : base(requestContext)
        {

        }

        protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            var url = RequestContext.RouteData.Values["path"].ToString();
            var page = SomePageService.GetPageByUrl(url);

            if (page == null)
            {
                RequestContext.RouteData.Values["Action"] = "NotFound";
            }
            else
            {
                RequestContext.RouteData.Values["Action"] = page.Action;
                RequestContext.RouteData.Values["page"] = page;
            }

            return base.BeginProcessRequest(httpContext, callback, state);
        }
    }
4

1 に答える 1

4

おそらくあなたの状況に対する正確な解決策ではないかもしれませんが、私は最近、あなたを正しい方向に向けるかもしれないので、同様の何かを処理しなければなりませんでした。

私が行ったのは、カスタムRouteHandlerクラスを呼び出すcatch-allパラメーターを使用してGlobal.asaxに単純なルートを設定することでした。

// Custom MVC route
routes.MapRoute(
    "Custom",
    "{lang}/{*path}",
    new { controller = "Default", action = "Index" },
    new { lang = @"fr|en" }
).RouteHandler = new ApplicationRouteHandler();

ApplicationRouteHandler.cs:

public class ApplicationRouteHandler : IRouteHandler
{
    /// <summary>
    /// Provides the object that processes the request.
    /// </summary>
    /// <param name="requestContext">An object that encapsulates information about the request.</param>
    /// <returns>
    /// An object that processes the request.
    /// </returns>
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string path = requestContext.RouteData.Values["path"] as string;
    // attempt to retrieve controller and action for current path
        Page page = GetPageData(path);

    // Method that returns a 404 error
        if (page == null)
            return SetupErrorHandler(requestContext, "ApplicationRouteHandler");

    // Assign route values to current requestContext
        requestContext.RouteData.Values["controller"] = page.Controller;
        requestContext.RouteData.Values["action"] = page.Action;
        return new MvcHandler(requestContext);
    }
}

明らかに、データベースからアクションとコントローラーの名前を取得する方法は、おそらく私のものとは大きく異なりますが、これでアイデアが得られるはずです。

于 2012-08-27T14:01:08.540 に答える