2010-10-20 43 views
6

¡Estoy a punto de darme por vencido en esta aplicación de mvc por hoy!MVC Error: Referencia de objeto no establecida en una instancia de un objeto

que sigo MVC Music Store Tutorial y estoy atascado en la página 54.

este es el error que estoy consiguiendo:

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

El error se produce en el tercer bloque el párrafo (lista desplegable) en el siguiente código:

<%@ Import Namespace ="MvcMovies1" %> 
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMovies1.Models.Album>" %> 

<p> 
    <%: Html.LabelFor(model => model.Title) %> 
    <%: Html.TextAreaFor(model => model.Title) %> 
    <%: Html.ValidationMessageFor(model => model.Title) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.Price) %> 
    <%: Html.TextAreaFor(model => model.Price) %> 
    <%: Html.ValidationMessageFor(model => model.Price) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.AlbumArtUrl) %> 
    <%: Html.TextAreaFor(model => model.AlbumArtUrl) %> 
    <%: Html.ValidationMessageFor(model => model.AlbumArtUrl) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.Artist) %> 
    <%: Html.DropDownList("ArtistId", new SelectList(ViewData["Artists"] as IEnumerable, "ArtistId", "Name", Model.ArtistId)) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.Genre) %> 
    <%: Html.DropDownList("GenreId", new SelectList(ViewData["Genres"] as IEnumerable, "GenreId", "Name", Model.GenreId)) %> 
</p> 

    <div> 
     <%: Html.ActionLink("Back to List", "Index") %> 
    </div> 

Este ascx está contenido dentro de un archivo Edit.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcMovies1.ViewModels.StoreManagerViewModel>" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Edit 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
<form id="form1" runat="server"> 
    <h2>Edit</h2> 
    <% using (Html.BeginForm()) 
     { %> 
     <%: Html.ValidationSummary(true)%> 

    <fieldset> 
     <legend>Edit Album</legend> 
     <%: Html.EditorFor(model => model.Album, 
      new { Artists = Model.Artists, Genres = Model.Genres }) %> 

      <p><input type="submit" value="Save" /></p> 


    </fieldset> 

     <% } %> 
     </form> 
</asp:Content> 

Me doy cuenta de que hay un montón de código allí, pero si alguien puede ver algo obvio que estoy haciendo algo malo, estaría muy agradecido.

EDITAR

StoreManagerController.cs (Editar)

public ActionResult Edit(int id) 
    { 
     var viewModel = new StoreManagerViewModel 
     { 
      Album = storeDB.Albums.SingleOrDefault(a => a.AlbumId == id), 
      Genres = storeDB.Genres.ToList(), 
      Artists = storeDB.Artists.ToList() 
     }; 

     return View(viewModel); 
    } 

Andddd..StoreManagerViewModel.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using MvcMovies1.Models; 

namespace MvcMovies1.ViewModels 
{ 
    public class StoreManagerViewModel 
    { 
     public Album Album { get; set; } 
     public List<Artist> Artists { get; set; } 
     public List<Genre> Genres { get; set; } 
    } 
} 

Una vez más me doy cuenta de lo llamé MvcMovies1, esto fue un error pero todo es marcado en consecuencia.

+4

Puedes publicar tu acción en tu controlador también. ¿Está configurando ViewData ["Artistas"] en el controlador? – lancscoder

+0

Hola Simon G. He publicado el código solicitado. Gracias por la respuesta. – 109221793

+0

¿Puede poner un punto de interrupción en esa línea y verificar todas las propiedades de nulos? – Rup

Respuesta

6

¿Tiene Album tienen un ArtistId ya que en esa línea que está llamando Model.ArtistId y si Album no tiene esa propiedad en que obtendrá una excepción de referencia nula. Esto se debe a que el Modelo es una abreviatura del objeto que está fuertemente tipado en su vista, que en su caso es Album.

No hay ningún lugar en su código anterior donde está configurando ViewData ["Artistas"]. ¿Estás estableciendo eso en cualquier lugar ya que ese también podría ser tu problema?

EDITAR

Establecer la ViewData en la acción y debería funcionar:

public ActionResult Edit(int id) 
{ 
    var viewModel = new StoreManagerViewModel 
    { 
     Album = storeDB.Albums.SingleOrDefault(a => a.AlbumId == id), 
     Genres = storeDB.Genres.ToList(), 
     Artists = storeDB.Artists.ToList() 
    }; 

    ViewData["Artists"] = storeDB.Artists.ToList(); 
    ViewData["Genres"] = storeDB.Genres.ToList(); 

    return View(viewModel); 
} 
+1

Pero dado que el modelo está fuertemente tipado, ¿no compilaría la página si faltara ArtistId en lugar de arrojar una excepción de referencia nula? – Rup

+0

Hola amurra ... Creo que es ViewData ["Artistas"] este es mi problema. ¡Solo estoy aprendiendo Mvc así que literalmente he seguido lo que estaba en el tutorial así que estoy perplejo! – 109221793

+0

@Rup - Creo que solo si está compilando las vistas se mostrará entonces, de lo contrario se encontraría durante el tiempo de ejecución – amurra

2

ur simplemente no establecer ViewData [ "artistas"] y ViewData [ "géneros"] como puedo c de tu método de acción.asegurarse ur establecer estos valores en algún lugar durante la vida de una solicitud si quieres usarlos en ur vista

+0

¿No está fusionado en el ViewData por la llamada 'EditorFor'? Lo está pasando en el parámetro adicional ViewData http://msdn.microsoft.com/en-us/library/ff406462.aspx – Rup

+7

por favor deletree 'usted' en lugar de 'usted'. esto no es twitter – automagic

+2

@james u obtienes lo que es el punto –

6

En primer lugar es necesario agregar propiedades en su modelo de vista para contener artista seleccionado y género seleccionado:

public class StoreManagerViewModel 
{ 
    public Album Album { get; set; } 
    public int? SelectedArtistId { get; set; } 
    public List<Artist> Artists { get; set; } 
    public int? SelectedGenreId { get; set; } 
    public List<Genre> Genres { get; set; } 
} 

a continuación, en su opinión, en lugar de Edit.aspx:

<%: Html.EditorFor(model => model.Album, 
    new { Artists = Model.Artists, Genres = Model.Genres }) %> 

usted podría simplemente:

<%: Html.EditorForModel() %> 

y en su editor de plantillas ~/Views/Home/EditorTemplates/Album.ascx:

<%@ Import Namespace ="MvcMovies1" %> 
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMovies1.Models.Album>" %> 

<p> 
    <%: Html.LabelFor(model => model.Title) %> 
    <%: Html.TextAreaFor(model => model.Title) %> 
    <%: Html.ValidationMessageFor(model => model.Title) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.Price) %> 
    <%: Html.TextAreaFor(model => model.Price) %> 
    <%: Html.ValidationMessageFor(model => model.Price) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.AlbumArtUrl) %> 
    <%: Html.TextAreaFor(model => model.AlbumArtUrl) %> 
    <%: Html.ValidationMessageFor(model => model.AlbumArtUrl) %> 
</p> 

y en su editor de plantillas ~/Views/Home/EditorTemplates/StoreManagerViewModel:

<%@ Import Namespace ="MvcMovies1" %> 
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMovies1.ViewModels.StoreManagerViewModel>" %> 

<%: Html.EditorFor(model => model.Album) %> 

<p> 
    <%: Html.LabelFor(model => model.SelectedArtistId) %> 
    <%: Html.DropDownListFor(model => model.SelectedArtistId, new SelectList(Model.Artists, "ArtistId", "Name")) %> 
</p> 

<p> 
    <%: Html.LabelFor(model => model.SelectedGenreId) %> 
    <%: Html.DropDownListFor(model => model.SelectedGenreId, new SelectList(Model.Genres, "GenreId", "Name")) %> 
</p> 

<div> 
    <%: Html.ActionLink("Back to List", "Index") %> 
</div> 
+0

Hola Darin, parece que sabes tus cosas, pero una cosa que no entiendo es ¿por qué el archivo Album.ascx ahora se divide en dos archivos diferentes? – 109221793

+1

Debido a que para una mejor separación de preocupaciones, la plantilla del editor de álbumes solo debe preocuparse por las propiedades del álbum y no por los géneros y artistas que están disociados. También evita que trabajes con feos ViewState y cadenas mágicas y que emitan a IEnumerable, siempre es preferible trabajar con tipeo fuerte. –

+0

Hmm, está bien. En el tutorial, verá que los cuadros de texto html, las etiquetas, las listas desplegables, etc. están todos en el único archivo. Me gustaría seguir eso lo más cerca que pueda. Si tuviera que unir los dos anteriores en uno, ¿estaría bien trabajar con eso? – 109221793

1

has necesitado fundición a la lista y la lista en lugar de IEnumerable?

0

problema: Referencia a objeto no establecida como instancia de un objeto Solución:

 pubblic ActionResult yourDetails() 
{ 
    List<YourEntityName> PropertyName= new List<YourEntityName>(); 
       list= db.PropertyName.ToList(); 
       return View(list); 
} 

YourEntityName significa que su nombre de la tabla es decir PassengerDetial PropertyName media de propiedad pubblic su clase es decir PassengerDetails

pubblic Class PassengerDetailContext : DbContext 
{ 
    pubblic DbSet<PassengerDetail> passegerDetails {get;set;} 
} 



List<PassengerDetail> passegerDetails = new List<PassengerDetail>(); 
       list= db.passegerDetails .ToList(); 
       return View(list); 
0

había el mismo error al intentar ejecutar la migración (actualización de la base de datos). tenía 2 proyectos a saber ViewProject y DBcontextProject.

mi problema fue que hice de ViewProject un proyecto de inicio y ejecuté la migración en DBcontextProject.

La solución fue hacer de DBcontextProject un proyecto de inicio y ejecutar la migración en DBcontextProject.

Cuestiones relacionadas