简体   繁体   English

实体框架.find(id)NullReferenceException

[英]entity framework .find(id) NullReferenceException

I am working through the MVC Music Store tutorial , and have come across a small problem / query. 我正在通过MVC音乐商店教程学习 ,并且遇到了一个小问题/查询。

I am looking to find an album by it's id. 我想通过ID查找专辑。

var album = db.Albums.Find(id)

This works fine however, if the id does not exist, then I get a NullReferenceException when the controller passes a null model to the view. 但是,如果id不存在,则工作正常,然后当控制器将null模型传递给视图时,我得到了NullReferenceException。

I can think of 2 ways to fix this. 我可以想出两种解决方法。

Method 1: Check for null in controller, if null, show a different view / redirect to a different action such as an index page or dedicated error page / 404 not found page. 方法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);
    }

Method 2: Check if model is null in the view, if so, don't show model specific items, but instead show an error message. 方法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>
}

The Question: Are there any other ways / best practice ways of dealing with this? 问题:还有其他方法/ 最佳实践方法来解决此问题吗? Are there any advantages of method 1, vs method 2? 与方法2相比,方法1有什么优势吗?

You could write a custom action filter that will check if the model passed to the view is null and render a 404 page. 您可以编写一个自定义操作过滤器,该过滤器将检查传递给视图的模型是否为null并呈现404页面。 This way you don't need to repeat this logic in all controller actions: 这样,您无需在所有控制器操作中都重复此逻辑:

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;
        }
    }
}

and then: 接着:

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

Alternative approach consists in writing a custom route by deriving from the Route class in which you would retrieve the model and if it is not found simply do not match the route. 另一种方法是通过从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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM