artist and genre problem upon create/edit

Oct 26, 2010 at 2:27 PM

the tutorial is really helpful however there are some problems I've encountered using VS 2008. The .single method throws an exception so i had to use .first.

Another thing that I have found is that Genre and Artist doesn't get updated whenever I click save when editing and it throws null exception when creating. It seems that the object album doesn't get updated when the event edit and create is trigger. I don't know if this is vs 2008 specific problem. 

Here's my controller code for edit and create

 

      //
        // POST: /StoreManager/Create

        [HttpPost]
        public ActionResult Create(Album album)
        {
            try
            {
                // TODO: Add insert logic here
                storeDB.AddToAlbum(album);
                storeDB.SaveChanges();

                return Redirect("/");
            }
            catch
            {
                // invalid - redisplay with errors

                var viewModel = new StoreManagerViewModel
                {
                    Album = album,
                    Genres = storeDB.Genre.ToList(),
                    Artists = storeDB.Artist.ToList()
                };

                return View(viewModel);
            }
        }


        //
        // POST: /StoreManager/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            var album = storeDB.Album
                .First(a => a.AlbumId == id);
        
            try
            {
                // save album

                UpdateModel(album, "Album");                               
                storeDB.SaveChanges();

                return RedirectToAction("Index");
            }
            catch
            {
                var viewModel = new StoreManagerViewModel
                {
                    Album = album,
                    Genres = storeDB.Genre.ToList(),
                    Artists = storeDB.Artist.ToList()
                };

                return View(viewModel);
            }
        }

And here's my ascx code for the dropdown list of genres and artist
   
    <div class="editor-field">
        <%= Model.Artist == null ? Html.DropDownList("ArtistId", new SelectList(ViewData["Artists"] as IEnumerable,
                "ArtistId", "Name")) 
                        : Html.DropDownList("ArtistId", new SelectList(ViewData["Artists"] as IEnumerable,
                "ArtistId", "Name", Model.Artist.ArtistId))%>
    </div>
    <div class="editor-label">
        <%= Html.LabelFor(model => model.Genre) %>
    </div>
    <div class="editor-field">
        <%= Model.Genre == null ? Html.DropDownList("GenreId", new SelectList(ViewData["Genres"] as IEnumerable,
                "GenreId", "Name"))
                        : Html.DropDownList("GenreId", new SelectList(ViewData["Genres"] as IEnumerable,
                "GenreId", "Name", Model.Genre.GenreId))%>
    </div>

I hope someone can help me with this. I am really stuck on this module.

Coordinator
Nov 4, 2010 at 7:59 PM

Your Album.ascx code doesn't match what's on p.81 of the tutorial (v1.0):


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMusicStore.Models.Album>" %>
<p> <%: Html.LabelFor(model => model.Title)%> <%: Html.TextBoxFor(model => model.Title)%> <%: Html.ValidationMessageFor(model => model.Title)%>
</p>
<p> <%: Html.LabelFor(model => model.Price)%> <%: Html.TextBoxFor(model => model.Price)%> <%: Html.ValidationMessageFor(model => model.Price)%>
</p>
<p> <%: Html.LabelFor(model => model.AlbumArtUrl)%> <%: Html.TextBoxFor(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>

 What page of the tutorial are you on?

Nov 11, 2010 at 7:57 AM

I'm facing the same prob. Still can't get through, even when i directly copied the source codes from the pdf.

Please take a look. (I did changed the MvcMusicStore to MvcMusicApp just to compare both)

 

// Album.ascx //

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMusicApp.Models.Album>" %>
<p> <%: Html.LabelFor(model => model.Title)%>
 <%: Html.TextBoxFor(model => model.Title)%> 
 <%: Html.ValidationMessageFor(model => model.Title)%>
</p>
<p> <%: Html.LabelFor(model => model.Price)%> 
<%: Html.TextBoxFor(model => model.Price)%> 
<%: Html.ValidationMessageFor(model => model.Price)%>
</p>
<p> <%: Html.LabelFor(model => model.AlbumArtUrl)%> 
<%: Html.TextBoxFor(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>

 

// Edit.aspx //

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<MvcMusicApp.View_Models.StoreManagerViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
Edit - <%: Model.Album.Title %>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Album</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>

<% } %>

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

 

//StoreManagerController.cs

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

        //
        // POST: /StoreManager/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection formValues)
        {
            var album = StoreDB.Albums.Single(a => a.AlbumId == id);
            try
            {
                //Save Album
                UpdateModel(album, "Album");
                StoreDB.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                //Error occurred � so redisplay the form
                var viewModel = new StoreManagerViewModel
                {
                    Album = album,
                    Genres = StoreDB.Genres.ToList(),
                    Artists = StoreDB.Artists.ToList()
                };
                return View(viewModel);
            }
        }


Nov 11, 2010 at 8:13 AM
Edited Nov 11, 2010 at 8:22 AM

Oh, btw. It's still showing numbers rather than names. Also, no dropdowns. And no errors also~

Nov 27, 2010 at 2:37 AM
Edited Nov 27, 2010 at 2:57 AM

I think this is the copy of the MVCMusicStore.mdf.  In the tutorial ArtistID and GenreID  are access as a member of the Album table like album.GenreID  album.ArtistID. If you take a look at the OP supplied code.
he has to go album.Artist.ArtistID  album.Genre.GenreID  and the problem that occurs is on the

 

 

try
            {
                // save album

                UpdateModel(album, "Album");                               
                storeDB.SaveChanges();

                return RedirectToAction("Index");
            }

 

after the UpdateModel(album, "Album");  the album collection Artist and Genre is null.  Now i think i have found a fix for ease of use.  I think you download the Assest only like i did originally. If you download the complete Mvcmusicstore-v1.0,

browse to the folder \\MvcMusicStore-v1.0\MvcMusicStore-Completed\MvcMusicStore\App_Data  and take the DB from that folder and add it to your project instead. 

I have done this but now i seem to have a new problem. Inspecting this "New" DB the tables are correct in that album.ArtistID is now a vaild call. but in my project  the DB association seems to still be with the old mvcmusicstore.mdf

EDIT:
I have deleted my storeDB.edmx and remade the DB connection but its still the same cannot access album.ArtistID album.GenreID directly.  I am not sure if this is the reason why artist and genre are not save i just no the values return null after the UpdateModel from the form data.

Feb 16, 2011 at 11:11 PM

im havin that exact problem i hope someone could help us on this one

May 20, 2011 at 10:55 PM

Does anyone have a solution with this problem?

The problem here is that the Thread Starter uses EF3.5 (VS2008 not 2010) that, unlike EF4.0, does not have the option to include foreign keys as fields (ArtistId and GenreId will not be added as Property of the Album Entity).

<%: Html.DropDownList("ArtistId", new SelectList(ViewData["Artists"] as IEnumerable, "ArtistId", "Name", Model.ArtistId))%>
<%: Html.DropDownList("GenreId", new SelectList(ViewData["Genres"] as IEnumerable, "GenreId", "Name", Model.GenreId))%>

Model.ArtistId and Model.GenreId would not be valid since they are not properties of the Album object.

The process somehow fails to assign values for Genre and Artist property of the Album object based on the selected value on the DropDownList.

Any thoughts?