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:
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!
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With