2

我正在通過MVC Music Store tutorial工作,並遇到了一個小問題/查詢。實體框架.find(id)NullReferenceException

我期待通過它的ID找到相冊。

var album = db.Albums.Find(id)

然而,這工作得很好,如果ID不存在,然後我得到一個NullReferenceException當控制器通過一個空模型視圖。

我可以想出2種方法來解決這個問題。方法1:檢查控制器中的空值,如果爲null,則顯示不同的視圖/重定向到不同的操作,如索引頁或專用錯誤頁/ 404找不到頁面。方法2:檢查模型在視圖中是否爲空,如果是,則不顯示模型特定項目,而是顯示錯誤消息。

@model MvcMusicStore.Models.Album 
@{ 
    ViewBag.Title = "Details"; 
} 
@if (Model == null) 
{ 
    <h2>That album doesn't exist</h2> 
} 
else 
{ 
    <h2>Details: @Model.Title</h2> 
} 

的問題是:是否有任何其他方式/ 最佳實踐方式處理這個問題?方法1和方法2有什麼優點?

回答

4

您可以編寫一個自定義操作篩選器,檢查傳遞給視圖的模型是否爲null並呈現404頁面。這樣,您就不需要再重複這樣的邏輯在所有的控制器動作:

public class CheckForEmptyModelAttribute: ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     var viewResult = filterContext.Result as ViewResultBase; 
     if (viewResult != null && viewResult.Model == null) 
     { 
      var view404 = new ViewResult 
      { 
       ViewName = "~/Views/Shared/404.cshtml" 
      }; 
      filterContext.Result = view404; 
     } 
    } 
} 

然後:

// 
// GET: /Store/Details/4 
[CheckForEmptyModel] 
public ActionResult Details(int? id) 
{ 
    var album = db.Albums.Find(id); 
    return View(album); 
} 

替代方法包括通過從Route類派生編寫定製的路線,你將檢索模型,如果沒有找到,只是不匹配的路線。

0
// 
// GET: /Store/Details/4 
public ActionResult Details(int? id) 
{ 
    var album = db.Albums.Find(id); 
    return ViewIfNotNull(album); 
} 

// boxing 
private ActionResult ViewIfNotNull(object model) 
{ 
    if (album == null) return RedirectToAction("Index"); 
    else return View(album); 
} 

// OR generic 
private ActionResult ViewIfNotNull<T>(T model) 
{ 
    if (album == null) return RedirectToAction("Index"); 
    else return View(album); 
}