2016-06-23 2 views
0

自分のダイナミックルータを実装しようとしています。私の計画はデータベースからルートを取得し、ダイナミックなランディングページを作成することです。 404。context.RouteDataを新しいルートデータに設定した後、404。IRouterの実装で取得するASP.NET Core MVC

私はルートを見つけるたびにLandingPageControllerとIndex IActionResultにリダイレクトしたいだけです。

using System.Threading.Tasks; 
using Microsoft.AspNetCore.Routing; 
using System.Collections.Generic; 
using System.Linq; 

namespace Myproject.Web.Main.Config 
{ 
    public class LandingPageRouter : IRouter 
    { 
     public VirtualPathData GetVirtualPath(VirtualPathContext context) 
     { 
      return null; 
     } 

     public Task RouteAsync(RouteContext context) 
     { 

      var requestPath = context.HttpContext.Request.Path.Value; 
      if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/') 
      { 
       requestPath = requestPath.Substring(1); 
      } 

      var pagefound = GetPages().Any(x => x == requestPath); 
      if (pagefound) 
      { 
       //TODO: Handle querystrings 
       var routeData = new RouteData(); 
       routeData.Values["controller"] = "LandingPage"; 
       routeData.Values["action"] = "Index"; 
       context.RouteData = routeData; 
      } 

      return Task.FromResult(0); 
     } 

     private IEnumerable<string> GetPages() 
     { 
      //TODO: pull from database 
      return new List<string> { "page-url-title", "another-dynamic-url" }; 
     } 
    } 
} 

私はこのanswerに見えたが、時代遅れ文脈でいくつかのプロパティでもRC2にはもはや存在しないようです。

何が欠けていますか?

+0

用語MVC6の使用を中止してください。新しいバージョンのレガシーMVCがリリースされると、混乱が広がります。以前の "ASP.NET 5 MVC6"は、ASP.NET MVC5の次のバージョンではなく**完全に新しいフレームワークであることを明確に**するために、 "ASP.NET Core MVC 1.0"と命名されました**。また、正しいタグは 'asp.net-core-mvc'です! – Tseng

+0

興味深いシナリオのように見えます...もっと詳しい情報を教えてください。したがって、 '/ articles/cavaliers-win-nba-title'のようなリクエストが'/articles/10' urlにマップされ、 'articles'コントローラによって処理され、記事ID '10'また、リンクが生成されたときに、マッピングが他の方法で行われるようにするには...そうですか? –

+0

@KiranChallaルートレベルでmydomain.com/name-of-the-articleのようなルートを設定し、内部的にそれらのルートを私のLanding Pageコントローラにマップしたいと思っています。これはlandingpage/Idかlandingpage/name-記事の –

答えて

0

このanswerと@sockアプローチに基づいて、私は同時にルータコンテキスト

public LandingPageRouter(IRouteBuilder routeBuilder) 
{ 
    _routeBuilder = routeBuilder; 
} 

public Task RouteAsync(RouteContext context) 
{ 
    var requestPath = context.HttpContext.Request.Path.Value; 
    if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/') 
    { 
     requestPath = requestPath.Substring(1); 
    } 

    var pagefound = GetPages().SingleOrDefault(x => x.Name == requestPath); 
    if (pagefound!=null) 
    { 
     //TODO: Handle querystrings 
     var routeData = new RouteData(); 
     routeData.Values["controller"] = "LandingPage"; 
     routeData.Values["action"] = "Index"; 
     routeData.Values["id"] = pagefound.Id; 

     context.RouteData = routeData; 
     return _routeBuilder.DefaultHandler.RouteAsync(context); 
    } 
    return Task.FromResult(0); 
} 

ルートを渡すために起こっているルートビルダーを通過しましたstartup.csの設定例

app.UseMvc(routes => 
{ 
    routes.MapRoute(
    name: "default", 
    template: "{controller=Home}/{action=Index}/{id?}"); 

    routes.Routes.Add(new LandingPageRouter(routes)); 
} 
+0

嬉しいことに、あなたがリンクしている答えが、あなたの答えの中の 'IRouteBuilder'ではなく、' DefaultHandler'で直接渡されたように見えます - それらの違いがどういう意味なのでしょうか。尋ねると尋ねるのはちょっと質問するだけでしょうか? – Sock

+0

Githubで複製された自分の投稿でしたが、基本的には、 "ルート"(app.UseMvcの式)がIRoutebuilderを実装しているので、パラメータとして渡すのが自然な感じですドキュメントの不足による私の意見は、両方の実装の違いを説明するのは難しいです –

2

これは最も良い解決策のようには見えませんが、私のテストではあなたの要件に適合するはずです。


私はあなたのLandingPageRouterにデフォルトMVC IRouterを注入しました。あなたはルートデータを更新した後、次に、単にデフォルトルータを呼び出し、コンテキストに渡します

public class LandingPageRouter : IRouter 
{ 
    private readonly IRouter _router; 

    public LandingPageRouter(IRouter router) 
    { 
     _router = router; 
    } 

    public VirtualPathData GetVirtualPath(VirtualPathContext context) 
    { 
     return null; 
    } 

    public Task RouteAsync(RouteContext context) 
    { 

     var requestPath = context.HttpContext.Request.Path.Value; 
     if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/') 
     { 
      requestPath = requestPath.Substring(1); 
     } 

     var pagefound = GetPages().Any(x => x == requestPath); 
     if (pagefound) 
     { 
      //TODO: Handle querystrings 
      var routeData = new RouteData(); 
      routeData.Values["controller"] = "LandingPage"; 
      routeData.Values["action"] = "Index"; 
      context.RouteData = routeData; 
      return _router.RouteAsync(context); 
     } 

     return Task.FromResult(0); 
    } 

    private IEnumerable<string> GetPages() 
    { 
     //TODO: pull from database 
     return new List<string> { "page-url-title", "another-dynamic-url" }; 
    } 
} 

それからちょうどあなたがStartup.Configureであなたのルートを追加している場所にデフォルトルートを挿入します。

app.UseMvc(routes => 
{ 
    routes.Routes.Add(new LandingPageRouter(routes.DefaultHandler)); 
    routes.MapRoute(
     name: "default", 
     template: "{controller=Home}/{action=Index}/{id?}"); 
}); 
+0

ありがとう、私はあなたが提案したものの同様のアプローチで終わったと確信してあなたの答えは、正しい道を指すために私を助ける! –

関連する問題