实体框架.find(id)NullReferenceException

时间:2013-06-23 16:14:09

标签: c# asp.net-mvc entity-framework razor nullreferenceexception

我正在处理MVC Music Store tutorial,并遇到了一个小问题/查询。

我希望找到一张专辑。

var album = db.Albums.Find(id)

这样可以正常工作,但是如果id不存在,那么当控制器将空模型传递给视图时,我会得到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:检查视图中的模型是否为空,如果是,则不显示特定于模型的项目,而是显示错误消息。

@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相比有什么优势吗?

2 个答案:

答案 0 :(得分: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类派生来编写自定义路线,在该类中将检索模型,如果找不到则只是与路径不匹配。

答案 1 :(得分: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);
}