0

Code:

@{
....    
var GotAllDetails = ViewData["GetAllDetails"] as List<PRJ.DetailViewsModel>;
....
}

and

@foreach (var goteem in GotAllDetails){Print my pretty list}

I've done plenty of debugging. I put a breakpoint right after var GetAllDetails, and I can confirm that ViewData["GetAllDetails"] is properly populated. The model I'm typecasting to has all the same value names and types as the ViewData. Yet, somehow, GotAllDetails is null. When the page hits my foreach it passes me

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Upon request, I'll share more code, but first tell me if I've made any obvious errors.

EDIT: Per Request, here's the code that specifies ViewData["GetAllDetails"]

ViewData["GetAllDetails"] = getAllDetails.OrderBy(q => PadString(q.TaskDescription, ".")).ToList();

And the LINQ Query

var getAllDetails =
    (from m in _db.MyStandards.AsEnumerable()
     join t in _db.Tasks on m.TaskId equals t.TaskId
     join p in _db.Products on t.ProductId equals p.ProductId
     join ce in _db.CompetencyElements on p.CompetencyElementId equals ce.CompetencyElementId
     join comp in _db.Competencies on ce.CompetencyId equals comp.CompetencyId
     join fu in _db.FunctionalUnitOfCompetences on comp.FunUnitOfCompetenceId equals fu.FunUnitOfCompetenceId
     join c in _db.Careers on fu.CareerId equals c.CareerId
     join rx in _db.RubricRefs on m.RubricStandardId equals rx.Id
     where (t.TaskId == m.TaskId && m.Email == getUserById && p.ProductId == proId)
     group new { t.TaskDescription, m.RubricStandardId, m.Comments }
     by new
     {
         c.CareerDescription,
         fu.FunUnitOfCompetenceDesc,
         comp.CompetencyDescription,
         ce.CompetencyElementdesc,
         p.ProductDescription,
         t.TaskDescription,
         m.RubricStandardId,
         m.Comments,
         m.StandardId,
         m.TaskId,
         m.ActiveInd,
         rx.RubricHexColor,
         rx.RubricSymbol
     } into g
     select new
     {
         ActiveInd = g.Key.ActiveInd,
         CareerDescription = g.Key.CareerDescription,
         Comments = g.Key.Comments,
         CompetencyDescription = g.Key.CompetencyDescription,
         CompetencyElementdesc = g.Key.CompetencyElementdesc,
         FunUnitOfCompetenceDesc = g.Key.FunUnitOfCompetenceDesc,
         ProductDescription = g.Key.ProductDescription,
         StandardId = g.Key.StandardId,
         RubricHexColor = g.Key.RubricHexColor,
         RubricStandardId = g.Key.RubricStandardId,
         RubricSymbol = g.Key.RubricSymbol,
         TaskDescription = g.Key.TaskDescription,
         TaskId = g.Key.TaskId,
     });

And the Model

public class DetailViewsModel
{
    public string ActiveInd { get; set; }
    public string  CareerDescription {get;set;}
    public string Comments {get;set;}
    public string CompetencyDescription {get;set;}
    public string CompetencyElementdesc {get;set;}
    public string FunUnitOfCompetenceDesc {get;set;}
    public string ProductDescription {get;set;}
    public int StandardId {get;set;}
    public string RubricHexColor {get;set;}
    public int RubricStandardId {get;set;}
    public string RubricSymbol {get;set;}
    public string TaskDescription {get;set;}
    public int TaskId {get;set;}
}
ekad
  • 14,436
  • 26
  • 44
  • 46
UIDAlexD
  • 218
  • 2
  • 12
  • 1
    "properly populated" means `ViewData["GetAllDetails"]` really returns a `List`? If the returned object is of a different type, the `as` operator returns `null`. – René Vogt Aug 05 '16 at 15:36
  • To the best of my knowledge, yes. The ViewData is coming from a LINQ Query, and I made sure that the model I'm typecasting into has all the same values as the output from said query. – UIDAlexD Aug 05 '16 at 15:43
  • 1
    My question was not if it has the same properties. You said you debugged it, so you can debug again and determine the real type. As I said, if it's not the correct type, `GotAllDetails` will be null. If it's the case, you'll need some kind of conversion. – René Vogt Aug 05 '16 at 15:50
  • You said `The ViewData is coming from a LINQ Query`, please show the controller code where you set `ViewData["GetAllDetails"]`. – ekad Aug 05 '16 at 16:07
  • @ekad Got you. It's posted now. – UIDAlexD Aug 05 '16 at 16:13
  • Try to change `var GotAllDetails = ViewData["GetAllDetails"] as List;` to `var GotAllDetails = (List)ViewData["GetAllDetails"];` and see if you get a different error. – ekad Aug 05 '16 at 16:40
  • @ekad Gave me an Invalid Cast Exception error. Worth a try, though. – UIDAlexD Aug 05 '16 at 16:53
  • I'm pretty sure the type of `ViewData["GetAllDetails"]` is not `List`. What's the complete error message? – ekad Aug 05 '16 at 16:55
  • @ekad **Exception Details** : System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[<>f__AnonymousType27`13[System.String,System.String,System.String,System.String,System.String,System.String,System.String,System.Int32,System.String,System.Nullable`1[System.Int32],System.String,System.String,System.Int32]]' to type 'System.Collections.Generic.List`1[PRJ.DetailViewsModel]'. – UIDAlexD Aug 05 '16 at 16:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/120264/discussion-between-ekad-and-uidalexd). – ekad Aug 05 '16 at 16:58

3 Answers3

2

This code:

new  {
    ActiveInd = g.Key.ActiveInd,
    CareerDescription = g.Key.CareerDescription,
    Comments = g.Key.Comments,
    CompetencyDescription = g.Key.CompetencyDescription,
    CompetencyElementdesc = g.Key.CompetencyElementdesc,
    FunUnitOfCompetenceDesc = g.Key.FunUnitOfCompetenceDesc,
    ProductDescription = g.Key.ProductDescription,
    StandardId = g.Key.StandardId,
    RubricHexColor = g.Key.RubricHexColor,
    RubricStandardId = g.Key.RubricStandardId,
    RubricSymbol = g.Key.RubricSymbol,
    TaskDescription = g.Key.TaskDescription,
    TaskId = g.Key.TaskId,
 });

... doesn't yield a DetailViewsModel. What it yields is a class that has the same property names and possibly property types, but it doesn't yield the SAME class.

You're going to have to instantiate an actual DetailsViewModel if you want what you are getting from getAllDetails to be castable to a List<DetailViewsModel>.

Fortunately, you've already done the hard part: setting all the property values! You should be able to substitute in this:

  new DetailsViewModel() {
      ActiveInd = etc.
Ann L.
  • 13,760
  • 5
  • 35
  • 66
  • It as really hard to choose between this and the other answer, but the plain-English explanation helped a lot. Thank you for breaking things down for me. – UIDAlexD Aug 05 '16 at 17:50
1

The problem comes from this syntax

var GotAllDetails = ViewData["GetAllDetails"] as List<PRJ.DetailViewsModel>;

According to MSDN

The as operator is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception.

Since you said ViewData["GetAllDetails"] isn't null, then GotAllDetails is null because the type of ViewData["GetAllDetails"] is not List<PRJ.DetailViewsModel>. You need to make sure the type of ViewData["GetAllDetails"] is List<PRJ.DetailViewsModel>.

Based on the linq query that produces getAllDetails in your question as below

var getAllDetails = ....
                    ....
                 select new
                 {
                     ActiveInd = g.Key.ActiveInd,
                     CareerDescription = g.Key.CareerDescription,
                     Comments = g.Key.Comments,
                     CompetencyDescription = g.Key.CompetencyDescription,
                     CompetencyElementdesc = g.Key.CompetencyElementdesc,
                     FunUnitOfCompetenceDesc = g.Key.FunUnitOfCompetenceDesc,
                     ProductDescription = g.Key.ProductDescription,
                     StandardId = g.Key.StandardId,
                     RubricHexColor = g.Key.RubricHexColor,
                     RubricStandardId = g.Key.RubricStandardId,
                     RubricSymbol = g.Key.RubricSymbol,
                     TaskDescription = g.Key.TaskDescription,
                     TaskId = g.Key.TaskId,
                 });

and how you set ViewData["GetAllDetails"]

ViewData["GetAllDetails"] = getAllDetails.OrderBy(q => PadString(q.TaskDescription, ".")).ToList();

it's clear that the type of ViewData["GetAllDetails"] is List<anonymous> instead of List<PRJ.DetailViewsModel>.

You need to change the linq query to below

var getAllDetails = ....
                    ....
                 select new DetailViewsModel
                 {
                     ActiveInd = g.Key.ActiveInd,
                     CareerDescription = g.Key.CareerDescription,
                     Comments = g.Key.Comments,
                     CompetencyDescription = g.Key.CompetencyDescription,
                     CompetencyElementdesc = g.Key.CompetencyElementdesc,
                     FunUnitOfCompetenceDesc = g.Key.FunUnitOfCompetenceDesc,
                     ProductDescription = g.Key.ProductDescription,
                     StandardId = g.Key.StandardId,
                     RubricHexColor = g.Key.RubricHexColor,
                     RubricStandardId = g.Key.RubricStandardId,
                     RubricSymbol = g.Key.RubricSymbol,
                     TaskDescription = g.Key.TaskDescription,
                     TaskId = g.Key.TaskId,
                 });

then change this

var GotAllDetails = ViewData["GetAllDetails"] as List<PRJ.DetailViewsModel>;

to this

var GotAllDetails = (List<PRJ.DetailViewsModel>)ViewData["GetAllDetails"];

so you'll know if the conversion fails.

ekad
  • 14,436
  • 26
  • 44
  • 46
0

ViewData is linked to Session. If you wish to remove your error try this.

var GotAlLDetails = ViewData["GetAllDetails"];

    if(GotAllDetails != null)
    {
    // do work
    }
  • It's a good failsafe, but I'm not in the market for a failsafe. Also, if I do this we get a compile time failure because `object does not contain a public definition for GetEnumerator.` – UIDAlexD Aug 05 '16 at 15:51