渲染视图时 foreach 出现奇怪的空引用错误

发布于 2024-10-08 19:16:25 字数 1605 浏览 2 评论 0原文

这个错误太奇怪了,我真的无法弄清楚到底出了什么问题!

在 UserController 中,

public virtual ActionResult Index()
{
    var usersmdl = from u in RepositoryFactory.GetUserRepo().GetAll()
                   select new UserViewModel
                   {
                       ID = u.ID,
                       UserName = u.Username,
                       UserGroupName = u.UserGroupMain.GroupName,
                       BranchName = u.Branch.BranchName,
                       Password = u.Password,
                       Ace = u.ACE,
                       CIF = u.CIF,
                       PF = u.PF
                   };
    if (usersmdl != null)
    {
        return View(usersmdl.AsEnumerable());
    }
    return View();
}

我的视图类型为 @model IEnumerable 位于顶部。
发生的情况是这样的:

alt text

到底在哪里以及什么是 null!?

我使用最小起订量从一个假存储库创建用户。我还编写了通过的单元测试,以确保返回适量的模拟用户。

也许有人可以在这里指出我正确的方向?堆栈跟踪的顶部是:

at lambda_method(Closure , User )
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at ASP.Index_cshtml.Execute() 

这与 linq 有关吗?告诉我是否应该包含完整的堆栈跟踪。


编辑
哇,我不敢相信这是 u.UserGroupMain.GroupName,谢谢 @Lunivore
这是一个模型存储库,我进行了单元测试来检查模拟存储库用户是否具有 UserGroupMain 的模拟实例,但我没有断言 wee 属性 GroupName已经设定了!

感谢@RPM1984,您建议获取代码来破坏控制器本身。另外我学到了一些新东西。

谢谢@Mikael,我第一次使用

我猜你生活、编码和学习!

This error is so weird I Just can't really figure out what is really wrong!

In UserController I have

public virtual ActionResult Index()
{
    var usersmdl = from u in RepositoryFactory.GetUserRepo().GetAll()
                   select new UserViewModel
                   {
                       ID = u.ID,
                       UserName = u.Username,
                       UserGroupName = u.UserGroupMain.GroupName,
                       BranchName = u.Branch.BranchName,
                       Password = u.Password,
                       Ace = u.ACE,
                       CIF = u.CIF,
                       PF = u.PF
                   };
    if (usersmdl != null)
    {
        return View(usersmdl.AsEnumerable());
    }
    return View();
}

My view is of type @model IEnumerable<UserViewModel> on the top.
This is what happens:

alt text

Where and what exactly IS null!?

I create the users from a fake repository with moq. I also wrote unit tests, which pass, to ensure the right amount of mocked users are returned.

Maybe someone can point me in the right direction here? Top of the stack trace is :

at lambda_method(Closure , User )
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at ASP.Index_cshtml.Execute() 

Is it something to do with linq here? Tell me If I should include the full stack trace.


Edit
<BangsHeadOnWall />
Wow, I cannot believe it was u.UserGroupMain.GroupName thanks @Lunivore.
It was a mockup repo, and I had a unit test to check if the mock repo user had a mock instance of UserGroupMain but I didn't Assert if the wee property GroupName had been set!

Thanks @RPM1984 you're suggestion got the code to break in the controller itself. Plus I learnt something new.

Thanks @Mikael, first time I used the immediate window wow its cool! =D

Guess you live, code and learn!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凡尘雨 2024-10-15 19:16:25

是的,它与 linq 有关。在您使用查询之前,Linq 不会执行该查询。因此,当您循环遍历它时,查询就会运行,但由于某种原因它会崩溃。

GetAll 返回什么?您可以做的一件事是在 Index() 内放置一个断点,当它中断时,将其写入立即窗口中。

>RepositoryFactory.GetUserRepo().GetAll().ToList()

如果你找不到立即窗口,你可以通过

>immed

在 findbox(VS 顶部)中

写入来打开它。如果这没有崩溃,问题可能出在 Index() 内的 linq 中。据我所知,我怀疑 u.UserGroupMain 或 u.Branch 为空。但如果没有更多信息,很难说。

Yeah, it got something to do with linq. Linq doesn't execute the query before you use it. So when you loop over it the query is run and for some reason it crashes.

What is GetAll returning? One thing you could do is to place a breakpoint inside Index() and when it breaks write this in the immediate window.

>RepositoryFactory.GetUserRepo().GetAll().ToList()

If you can't find the Immediate window you can open it by writing

>immed

in the findbox(in the top of VS)

If that doesn't crash the problem is probably in the linq inside Index(). From what I can see I would suspect that u.UserGroupMain or u.Branch is null. But hard to tell without more info.

我很OK 2024-10-15 19:16:25

将此行更改

return View(usersmdl.AsEnumerable());

为:

return View(usersmdl.ToList());

为什么?

来自 MSDN:

AsEnumerable(Of TSource)(IEnumerable(Of TSource)) 方法除了将源的编译时类型从实现 IEnumerable(Of T) 的类型更改为 IEnumerable(Of T) 本身之外没有任何作用。< /p>

英语 - 因为 .AsEnumerable() 转换为 IEnumerable,但 IQueryable 已经 实现IEnumerable,因此查询没有被具体化,并且当您枚举 foreach 中的项目时,查询会在视图中延迟计算。 LINQ 延迟执行的经典技巧。

这就是我喜欢 Resharper 的原因 - 它会告诉您 AsEnumerable() 调用是多余的 - 然后您的查询被推迟就会变得更加明显。

.ToList() 将在到达视图之前触发查询,并且仍然实现 IEnumerable,因此您的模型绑定不需要更改。

Change this line:

return View(usersmdl.AsEnumerable());

To this:

return View(usersmdl.ToList());

Why?

From MSDN:

The AsEnumerable(Of TSource)(IEnumerable(Of TSource)) method has no effect other than to change the compile-time type of source from a type that implements IEnumerable(Of T) to IEnumerable(Of T) itself.

In English - Because .AsEnumerable() converts to IEnumerable<T>, but IQueryable<T> already implements IEnumerable<T>, so the query is not being materialized - and is being lazily evaluated in the View when you enumerate the items in the foreach. Classic trick of LINQ deferred execution.

This is why i love Resharper - it will tell you the AsEnumerable() call is redundant - then it will become much more obvious your query is being deferred.

.ToList() will fire the query before it gets to the View, and still implements IEnumerable<T> so your model binding need not change.

烟织青萝梦 2024-10-15 19:16:25

检查您在用户中设置的 UserGroupMainBranch 是否不为空:

                   UserGroupName = u.UserGroupMain.GroupName,
                   BranchName = u.Branch.BranchName,

如果这解决了您的问题,Mikael 的答案解释了为什么会发生这种情况,而不是进一步在查询中。

Check that the UserGroupMain and Branch you've set up in your users aren't null:

                   UserGroupName = u.UserGroupMain.GroupName,
                   BranchName = u.Branch.BranchName,

If that fixes your problem, Mikael's answer explains why it was happening there and not further up in the query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文