2009-07-23 79 views
5

我有一個asp.net MVC 1.0站點當一切工作的權利文章映射到一個視圖,該視圖獲取呈現,供應從2級層次 /分類/文章如何在asp.net mvc中處理'View not found'InvalidOperationException?

一些內容。但是,當url滿足路由條件但視圖不存在時,會引發異常,導致無法捕獲控制器操作。

路由:

routes.MapRoute(
    "Article", 
    "{category}/{article}.aspx", 
    new { controller = "MyController", action = "Article" } 
); 

myController的操作:

public ActionResult Article(string category, string article) 
{ 
    string path = string.Format("~/Views/{0}/{1}.aspx", category, article); 
    ViewResult vr = View(path); 
    return vr; 
} 

然而,當未找到視圖,System.InvalidOperationException產生,我不能在控制器動作趕上。

異常詳細信息:System.InvalidOperationException:視圖 「〜/查看/我的類別/我 - 文章與 - 長name.aspx」或它的主人 找不到。以下地點搜索: 〜/查看/我的類別/我 - 文章與 - 長name.aspx

我就能夠在Application_Error()方法的錯誤global.asax.cs但:

  1. 不知道如何重定向到從那裏的錯誤視圖
  2. 想知道是否有更好的地方更接近於異常是 引發的地方。

回答

7

xandy,Greg, 我很感謝您的回答。這篇文章(Strategies For Resource Based 404 Errors in aspnet mvc)幫助我以非常乾淨的方式推導出我正在尋找的解決方案。我需要做的就是重寫控制器。onException的。由於我只需要一個控制器,我只需要在該控制器中重寫OnException。

這就是說,我的解決方案是治療症狀而不是疾病,因爲你們都建議,在調用這個之前檢查文件的存在會更好。查看路徑。

這裏是我用來治療症狀:)

protected override void OnException(ExceptionContext filterContext) 
{ 
    //InvalidOperationException is thrown if the path to the view 
    // cannot be resolved by the viewengine 
    if (filterContext.Exception is InvalidOperationException) 
    { 
     filterContext.ExceptionHandled = true; 
     filterContext.Result = View("~/Views/Error/NotFound.aspx"); 
     filterContext.HttpContext.Response.StatusCode = 404; 
    } 

    base.OnException(filterContext); 
} 

一個問題我解決不了的是如何在一個乾淨的方式顯示NOTFOUND查看代碼。通常通過ErrorController NotFound Action訪問它。我必須硬編碼它的路徑。我可以忍受這一點,但想知道是否有可能沒有HC路徑。

+0

我試過了,喜歡這個解決方案。唯一的問題是,如果你由於不同的原因而得到一個InvalidOperationException異常,它將導致404錯誤。當嘗試序列化某些東西時,會出現這樣的異常。 – Bealer 2011-11-04 05:55:15

0

我認爲檢查視圖是否存在的最佳位置是在控制器內。如果封裝視圖的構造函數不起作用,那麼它可能是ASP.net推遲了構造函數外部的View的實例化(不知道它是否是這樣)。

但您可能嘗試的一件事是手動檢查並查看路徑是否存在,使用Server.MapPath()獲取絕對文件路徑並檢查它是否存在。

0

我只是返回一個默認視圖,也許404響應將是適當的。當然,要做到這一點,你需要改變你的架構。

AFAIK您將需要一些代碼來檢查該文件是否存在,如在您的ASPX文件中,如果您不需要默認框架行爲。您可能應該使用ResolveURL or Url.Content來解析來自應用程序路徑的路徑。

作爲一個說明,通常,將您的域(文件名)暴露給世界並不是完全安全的。如果ASPX只是數據,那麼您應該將文本放入數據庫或普通的,不可執行的文本文件中。如果您正在構建某種CMS(即,您確實想要一種「安裝」功能的方式),那麼您可以考慮使用ASPX視圖來包含部分視圖來封裝ASP.NET代碼塊。

至於進入404頁面,this answer可能會有所幫助。

3

有一個合適的地方來處理這個問題。如果您實現自己的ViewEngine,則可以覆蓋「FileExists」方法。

public class ViewEngine : RazorViewEngine 
{ 
    protected override bool FileExists(ControllerContext context, string path) 
    { 
     if(!base.FileExists(context, path)) 
      throw new NotFoundException(); 

     return true; 
    } 

}

你只需要在Global.asax中像這樣註冊的視圖引擎,

ViewEngines.Engines.Clear(); 
ViewEngines.Engines.Add(new ViewEngine()); 

在的Application_Error可以實現映入NotFoundExceptions處理程序,記錄它們,然後通過執行ErrorController返回一個友好的消息。