C# 实体框架。查找(id)NullReferenceException

C# 实体框架。查找(id)NullReferenceException,c#,asp.net-mvc,entity-framework,razor,nullreferenceexception,C#,Asp.net Mvc,Entity Framework,Razor,Nullreferenceexception,我正在处理,遇到了一个小问题/疑问 我正在寻找一个专辑的id var album=db.Albums.Find(id) 但是,如果id不存在,那么当控制器将null模型传递给视图时,我会得到一个NullReferenceException 我可以想出两种方法来解决这个问题 方法1:在控制器中检查null,如果为null,则显示不同的视图/重定向到不同的操作,例如索引页或专用错误页/404未找到页 // // GET: /Store/Details/4 public Act

我正在处理,遇到了一个小问题/疑问

我正在寻找一个专辑的id

var album=db.Albums.Find(id)

但是,如果id不存在,那么当控制器将null模型传递给视图时,我会得到一个NullReferenceException

我可以想出两种方法来解决这个问题

方法1:在控制器中检查null,如果为null,则显示不同的视图/重定向到不同的操作,例如索引页或专用错误页/404未找到页

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

        if (album == null) return RedirectToAction("Index");
        else return View(album);
    }
方法2:检查视图中的模型是否为null,如果是,则不显示特定于模型的项,而是显示错误消息

@model MvcMusicStore.Models.Album
@{
    ViewBag.Title = "Details";
}
@if (Model == null)
{
    <h2>That album doesn't exist</h2>
} 
else 
{
    <h2>Details: @Model.Title</h2>
}
@model MvcMusicStore.Models.Album
@{
ViewBag.Title=“详细信息”;
}
@if(Model==null)
{
那张专辑不存在
} 
其他的
{
详细信息:@Model.Title
}

问题是:有没有其他方法来解决这个问题的最佳实践方法?与方法2相比,方法1有什么优点吗?

您可以编写一个自定义操作过滤器,用于检查传递给视图的模型是否为空,并呈现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
类派生来编写自定义路由,您将在该类中检索模型,如果找不到,则只需与路由不匹配。

您可以编写自定义操作筛选器,该筛选器将检查传递给视图的模型是否为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
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);
}
然后:

//
// GET: /Store/Details/4
[CheckForEmptyModel]
public ActionResult Details(int? id)
{
    var album = db.Albums.Find(id);
    return View(album);
}
另一种方法是通过从
route
类派生来编写自定义路由,您将在该类中检索模型,如果找不到该模型,只需与路由不匹配即可。

//
//
// 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);
}
//获取:/Store/Details/4 公共行动结果详细信息(int?id) { var album=db.Albums.Find(id); 返回ViewIfNotNull(相册); } //拳击 私有ActionResult ViewIfNotNull(对象模型) { 如果(相册==null)返回重定向到操作(“索引”); else返回视图(相册); } //或泛型 私有ActionResult视图IFNOTNULL(T模型) { 如果(相册==null)返回重定向到操作(“索引”); else返回视图(相册); }
//
//获取:/Store/Details/4
公共行动结果详细信息(int?id)
{
var album=db.Albums.Find(id);
返回ViewIfNotNull(相册);
}
//拳击
私有ActionResult ViewIfNotNull(对象模型)
{
如果(相册==null)返回重定向到操作(“索引”);
else返回视图(相册);
}
//或泛型
私有ActionResult视图IFNOTNULL(T模型)
{
如果(相册==null)返回重定向到操作(“索引”);
else返回视图(相册);
}