Asp.net-Mvc

使用 MVC 和 ASP.Net Core 重寫動態 url

  • October 26, 2016

我正在使用 ASP.Net Core 和 MVC 6 重寫我的 FragSwapper.com 網站(目前在 Asp 2.0 中!),我正在嘗試做一些我通常必須打破 URL Re-Write 工具和數據庫程式碼的事情和一些重定向,但我想知道在 ASP.Net Core 中是否有“更好”的方法可以使用 MVC 路由和重定向。

這是我的場景…

  • URL 訪問網站:$$ root $$

*怎麼辦:*去往常

$$ Home $$控制器和$$ Index $$查看(無$$ ID $$)。…它現在這樣做:

app.UseMvc(routes =>
{
 routes.MapRoute(
 name: "default",
 template: "{controller=Home}/{action=Index}/{id?}");
});
  • URL 訪問網站:$$ root $$/ControllerName/…亞達亞達…

*怎麼做:*去控制器,等等……這一切也都有效。

  • 棘手的一個: URL 訪問站點:$$ root $$/一些字元串

**怎麼辦:**訪問數據庫並執行一些邏輯來決定是否找到事件 ID。如果我這樣做,我會去

$$ Event $$控制器和$$ Index $$查看和$$ ID $$我發現的任何東西。如果不是,我嘗試查找主機 ID 並轉到$$ Home $$控制器和$$ Organization $$用那個查看$$ ID $$我發現。如果我沒有找到和事件或主持人去往常$$ Home $$控制器和$$ Index $$查看(無$$ ID $$).

這裡最大的問題是我想重定向到 2 個不同控制器中的三個完全不同的視圖之一。

所以底線是當使用者來到我的站點的根目錄並且上面有一個“/Something”並且該邏輯是數據庫驅動的時,我想做一些邏輯。

如果您理解這個問題,您現在可以停止閱讀……如果您覺得有必要了解為什麼需要所有這些邏輯,您可以繼續閱讀以獲得更詳細的上下文。

我的網站基本上有兩種模式:查看活動和不查看活動!通常一次執行 4 或 5 個事件,但大多數使用者只對一個事件感興趣,但它每 4 個月左右發生一次不同的事件..我有一個

$$ Host $$實體,每個主持人每年最多舉辦 4 場活動,一次一個。大多數使用者只關心一個主機的事件。 我試圖避免讓使用者總是去事件地圖並找到事件並點擊它,因為我可以顯示地圖的次數有限制(免費),這真的沒有必要。99.99% 的使用者在我的網站上的時間是在事件螢幕上,而不是在我的主螢幕上,並且一次只對一個事件感興趣。將來我想對其進行編碼,這樣如果他們訪問我的網站,他們就會直接參加他們的活動或來自他們最喜歡的主持人的新活動,這樣我就可以避免大量點擊並專注於我的

$$ Home $$新手的控制器頁面……但我還沒有自動登錄工作,所以這是次要的。 但現在我希望主持人始終擁有相同的活動網址:FragSwapper.com/

$$ Host Abbreviation $$…並且知道它總是會出現在他們目前的事件中,每 4 個月有一個不同的 ID !!! 瘋了…我知道…但從技術上講很容易做到,我只是不知道如何在 MVC 中正確地做到這一點。

更新:ASP.Net Core 1.1

根據發行說明RewriteMiddleware,已經創建了一個新的。

這提供了幾種不同的預定義重寫選項和實用程序擴展方法,最終可能會修改請求路徑,就像在此答案中所做的那樣。參見例如實現RewriteRule

具體到 OP 問題,您需要實現自己的IRule類(從頭開始或擴展現有的類RewriteRule,例如 ,它基於正則表達式)。你可能會用一個新的AddMyRule()擴展方法來補充它RewriteOptions


您可以創建自己的中間件並將其添加到 MVC 路由之前的請求管道中。

這允許您在評估 MVC 路由之前將程式碼注入管道。這樣,您將能夠:

  1. 檢查傳入請求中的路徑
  2. 在數據庫中搜尋具有相同值的 eventId 或 hostId
  3. 如果找到事件或主機,則將傳入請求路徑更新為Event/Index/{eventId}Home/Organization/{hostId}
  4. 讓下一個中間件(MVC 路由)處理請求。他們會看到之前的中間件對請求路徑所做的任何更改

例如,創建您自己的 EventIdUrlRewritingMiddleware中間件,該中間件將嘗試將傳入請求路徑與數據庫中的 eventId 進行匹配。如果匹配,它將原始請求路徑更改為Event/Index/{eventId}

public class EventIdUrlRewritingMiddleware
{
   private readonly RequestDelegate _next;        

   //Your constructor will have the dependencies needed for database access
   public EventIdUrlRewritingMiddleware(RequestDelegate next)
   {
       _next = next;
   }

   public async Task Invoke(HttpContext context)
   {
       var path = context.Request.Path.ToUriComponent();

       if (PathIsEventId(path))
       {
           //If is an eventId, change the request path to be "Event/Index/{path}" so it is handled by the event controller, index action
           context.Request.Path = "/Event/Index" + path;
       }

       //Let the next middleware (MVC routing) handle the request
       //In case the path was updated, the MVC routing will see the updated path
       await _next.Invoke(context);

   }

   private bool PathIsEventId(string path)
   {            
       //The real midleware will try to find an event in the database that matches the current path
       //In this example I am just using some hardcoded string
       if (path == "/someEventId")
       {
           return true;
       }

       return false;
   }
}

HostIdUrlRewritingMiddleware然後按照相同的方法創建另一個類。

最後在方法中將新的中間件添加到管道中Startup.Configure,確保它們在路由和 MVC 中間件之​​前添加:

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

使用此配置:

  • /HomeController.Index行動
  • /Home/AboutHomeController.About行動
  • /Event/Index/1轉到EventController.Index操作 id=1
  • /someEventIdEventController.Index行動,id=someEventId

請注意,不涉及 http 重定向。在瀏覽器中打開/someEventId時,只有一個 http 請求,瀏覽器將顯示/someEventId在地址欄中。(即使在內部更新了原始路徑)

引用自:https://stackoverflow.com/questions/36179304