2014-05-22 39 views
1

我們已經構建了一個MVC應用程序,該應用程序使用分層文件夾,子文件夾和頁面發佈完整的網站。結果頁面嚴格爲HTML,不會在我們的MVC應用程序中發佈。我們的客戶可以用他們選擇的任何符合字符串來命名他們的文件夾和頁面。因此,可以想象,一旦該網站託管,他們最終可能會得到一個URL,例如: someDomain.com/folder/subfolder1/subfolder2/page-slug。嵌套子文件夾的數量沒有限制。是否有可能在asp.net MVC 5中有一個匿名控制器?

我們希望在我們的MVC應用程序中複製他們的網站,以便他們能夠在發佈之前對其進行測試,或許我們可以根據需要自行提供託管服務。

明顯的問題是,我們該如何處理,在MVC應用程序中我們的MVCApp.com/folder/subfolder1/subfolder2/page-slug?

如果有一種方法可以設置路由來處理這樣的事情,那麼我們可以很容易地通過「/」將url分割成數組來獲得請求所需的內容。

最後一個段將是包含在前一個段的文件夾中的一個頁面。然後我們可以使用這些字符串搜索我們的數據庫以獲取所需的內容。

非常感謝您的幫助。

更多問題: 回覆Tomi提供的答案。

我添加的代碼到我的控制器的類,但我收到以下警告: enter image description here

我不知道我缺少的是什麼?我把代碼放在了什麼地方?再次感謝。

UPDATE 2.我意識到我並沒有真正創建控制器工廠,所以我遵循了我在這裏找到的部分示例:http://develoq.net/2010/custom-controller-factory-in-asp-net-mvc/。自從實現它之後,我不再收到任何構建錯誤,但是當我運行調試時,它會在沒有任何錯誤消息的情況下崩潰內置的IISEXPRESS。

這裏是我的控制器工廠代碼:

public class FolderControllerFactory : IControllerFactory 
{ 

    public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) 
    { 
     try 
     { 
      // Get the path 
      string path = requestContext.RouteData.Values["pathInfo"].ToString(); 

      IController controller = new FolderController(path); 

      return controller; 
     } 
     catch 
     { 
      // Log routing error here and move on 

      return CreateController(requestContext, controllerName); 

     } 
    } 


    public void ReleaseController(IController controller) 
    { 
     var disposable = controller as IDisposable; 
     if (disposable != null) 
     { 
      disposable.Dispose(); 
     } 
    } 

    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) 
    { 
     return SessionStateBehavior.Default; 
    } 

} 

這裏是我的世界:

ControllerBuilder.Current.SetControllerFactory(typeof(ProofPixApp.Controllers.FolderControllerFactory)); 

最後我的控制器:

public class FolderController : Controller 
{ 
    private string _path; 
    public FolderController(string path) 
    { 
     _path = path; 
    } 


    public ActionResult Index(string name) 
    { 
     ViewBag.Message = "Hello " + name; 
     return View("/Views/" + _path); 
    } 
} 

有兩點要注意:

1. I removed the 'override' from public IController CreateController 
    because I kept receiving the initial error I posted. 

    2. I added public void ReleaseController and the public 
     SessionStateBehavior GetControllerSessionBehavior methods to the 
     CreateController class to avoid other build errors. 

    3. I removed 'base.' from the catch clause because it too was causing a 
     build error. 

SOLUTION: 我能夠通過檢查pathValue避免該錯誤是不是在createController方法無效,就像這樣:

public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) 
    { 

     // Get the path 
     string path = ""; 
     if (requestContext.RouteData.Values["pathInfo"] != null) 
     { 
      path = requestContext.RouteData.Values["pathInfo"].ToString(); 
     } 

     IController controller = new FolderController(path); 

     return controller; 

    } 

回答

1

我不知道頁面蛞蝓是什麼,但這裏是我的解決方案如何實現您請求的路由。

我做了一個自定義ControllerFactory處理URL並將其傳遞給控制器​​。這個ControllerFactory構造了我們用來處理文件夾路由請求的控制器。我們從routevalues獲取路徑,然後將它傳遞給FolderController。

public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) 
    { 
     try 
     { 
      // Get the path 
      string path = requestContext.RouteData.Values["pathInfo"].ToString(); 

      IController controller = new FolderController(path); 

      return controller; 
     } 
     catch 
     { 
      // Log routing error here and move on 

      return base.CreateController(requestContext, controllerName); 
     } 
    } 

這裏是控制器。重定向到給定路徑的actionmethod稱爲現在的索引。 actionmethod返回它從url中找到的視圖。

public class FolderController : Controller 
{ 
    private string _path; 
    public FolderController(string path) 
    { 
     _path = path; 
    } 
    public FolderController() 
    { 
    } 

    public ActionResult Index(string name) 
    { 
     ViewBag.Message = "Hello " + name; 
     return View("/Views/"+_path); 
    } 
} 

最後一步是寫我們自己的路線並註冊工廠。打開RouteConfig.cs。我的新的RegisterRoutes方法是這樣的:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.MapRoute(
      name: "Dynamic", 
      url: "{*pathInfo}", 
      defaults: new { controller = "Folder", action = "Index", id = UrlParameter.Optional } 
      ); 
     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 

在Global.asax中,我們需要通過加入這一行到Application_Start方法中

ControllerBuilder.Current.SetControllerFactory(typeof(FolderControllerFactory)); 

就是這樣來註冊我們的FolderControllerFactory!還有很多工作要做,比如處理不當的網址等。另外我不認爲這支持純html文件,文件必須是.cshtml或asp格式。

這裏的測試:

我的文件夾結構:

Views folder in studio

網址我請求:

localhost:port/Mainfolder/Subfolder/Subfolder2/view.cshtml?name=Tomi 

與路線調試器插件結果:

Web page

+0

哇!非常感謝。我會在週一執行此操作。非常感謝! –

+0

嗨,托米,我編輯了我收到的警告圖像的問題。你可以看一下嗎? –

+0

也許你可以包含完整的控制器工廠代碼?我已經實現了我在這裏找到的一個版本,http://develoq.net/2010/custom-controller-factory-in-asp-net-mvc/,雖然我沒有構建錯誤了,但當我嘗試運行時該應用程序在本地,它會崩潰的內置IISExpress Web服務器沒有錯誤,提到。奇怪的。 –

相關問題