MVC MusicStore Artist.Name Link to an object is not installed in an instance of an object

Hacking your head while learning MVC through the MusicStore MVC. Received this error for Model.Artist.Name for the detail view page.

My Storecontroller Details method must be accurate.

public ActionResult Details(int id) { //returns and albums searched from the id var albums = storeDB.Albums.Find(id); return View(albums); } 

And this is how I am inferring the view

  <li>Price : <%=Model.Price %></li> <li>Artist : <%=Model.Artist.Name%></li> 

Works great for the price, and it only shows an error for Model.Genre.Name and Artist.Name. I suspect that declaring these properties in the sampledata.cs file caused this problem.

  Artist = artists.Single(a => a.Name == "Aaron Copland & London Symphony Orchestra") 

But my knowledge of this is too weak to come up with something. Please help.

Ok, the value is extracted from a class file that looks like this

  protected override void Seed(MusicStoreEntities context) { var artists = new List<Artist> { new Artist { Name = "Aaron Copland & London Symphony Orchestra" }, etcetc } new List<Album> { new Album { Title = "ABC", Artist= artists.Single(g => g.Name == "Test")} } } 

Notice how the value is assigned, I can access Model.Title fine (where the model is like a short hand), but Model.Artist.Name caused this error.

solvable

Ok, let this work by adding a virtual keyword to the Artist and Genre declaration in the Album class. But I'm still not sure what will happen, and would like someone to want to shed light.

In my Album class, before it is resolved, it looks like

 public class Album { public int AlbumId { get; set; } public int GenreId { get; set; } public int ArtistId { get; set; } public string Title { get; set; } public decimal Price { get; set; } public string AlbumArtUrl { get; set; } public Genre Genre { get; set; } public Artist Artist { get; set; } } 

The error caused by Genre and Artist is resolved by adding a virtual keyword

  public virtual Artist Artist { get; set; } 

Somehow, I still could not justify what was happening, and would like to know more. Anyone have to explain?

It happens so Album.cs

 namespace MvcMusicStore.Models { public class Album { public int AlbumId { get; set; } public int GenreId { get; set; } public int ArtistId { get; set; } public string Title { get; set; } public virtual Genre Genre { get; set; } public virtual Artist Artist { get; set; } } } 

using EF MusicStore.cs

 namespace MvcMusicStore.Models { //represent entity framework , handle create ,read , update and del ops public class MusicStoreEntities : DbContext { public DbSet<Album> Albums { get; set; } public DbSet<Genre> Genres { get; set; } public DbSet<Artist> Artists { get; set; } } } 

and implemented in StoreController.cs

  MusicStoreEntities storeDB = new MusicStoreEntities(); public ActionResult Details(int id) { //returns and albums searched from the id var albums = storeDB.Albums.Find(id); return View(albums); } 

Finally, sample data

 protected override void Seed(MusicStoreEntities context) { var artists = new List<Artist> { new Artist { Name = "Aaron Copland & London Symphony Orchestra" }, etcetc } new List<Album> { new Album { Title = "ABC", Artist= artists.Single(g => g.Name == "Test")} } } 
+4
source share
4 answers

Ok, I made money by adding a virtual keyword to the Artist and Genre ad in the Album class. But I'm still not sure what will happen, and I would like someone to want to shed some lights.

See above.

+2
source

You're right. The error is due to the fact that the Genre object and the Artist object were not created, and therefore an attempt to access the Name property either causes an error.

The problem occurs in the Find () method. If you are using LinqToSql, EF, NHibernate or simliar, check if your match is correct.

Update:

Based on the revised code, if you do artists.Single(g => g.Name == "Test") , then this will throw a NullReferenceException if there is no Artist named "Test" or something else.

I would advise making a match on something other than a string. Use Id to match if possible. This will provide a much more reliable matching condition.

Ideally, you should use SingleOrDefault() and check if null returned.

+3
source

It looks like Artist or Name null .

That is, the Artist of Model property does not have a reference to the initialized Artist instance or a similar script for the Name Artist instance. You should always check for null values ​​before trying to access an object:

 if (Model.Artist != null) { //do something with artist } 

The same explanation will mean other properties, such as Genre .

It is curious, however, that using Single to get only a single object should throw an exception if no Artist satisfies the request (or more than one of those requests) - is this your exact code, or the test that Artist really wants?

+2
source

GenreId, ArtistId, and AlbumId cannot be null Example:

 public int? GenreId { get; set; } 
0
source

All Articles