Hi, since I've spectacularly failed to build a simple MVC application (for now at least ) I've decided to do even a simpler one, modelled on this one http://www.codeproject.com/Articles/683942/An-Absolute-Beginners-Tutorial-for-understanding-E , which is supposed to create a few books and their associated reviews
I don't think it gets simpler than that. Naturally I run into some issues, but this time it seems to have to do only with the views. Let's look at the code.
So, I created my classes, as always in two separate files:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BooksApplication.Models
{
public class Book
{
public int BookID { get; set; }
public string BookName { get; set; }
public string ISBN { get; set; }
public virtual ICollection<Review> Reviews { get; set; } //1 book can have multiple reviews, 1 to many?
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BooksApplication.Models
{
public class Review
{
public int ReviewID { get; set; }
public string ReviewText { get; set; }
public int BookID { get; set; }//foreign key
public virtual Book Book { get; set; } // This apparently keeps track of the book this review belong to as ever
}
}
The I created the usual things, 2 controllers (BookController.cs and ReviewController.cs) with read and write action using EF respectively associated with Book (BooksApplication.Models) and Review (BooksApplication.Models) model classes and both with the same data context class BooksApplicationContext (BooksApplication.Models), here it is:
using System.Data.Entity;
namespace BooksApplication.Models
{
public class BooksApplicationContext : DbContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, add the following
// code to the Application_Start method in your Global.asax file.
// Note: this will destroy and re-create your database with every model change.
//
// System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<BooksApplication.Models.BooksApplicationContext>());
public BooksApplicationContext() : base("name=BooksApplicationContext")
{
}
public DbSet<Book> Books { get; set; }
public DbSet<Review> Reviews { get; set; }
}
}
So, I run a build and then tested both controllers, everything works fine, in that I can create books and multiple reviews for a single book. The thing is though, what I want to do is to be able to navigate to a specific book detail page, say
http://localhost:xxxxxx/Book/Details/1 and see not only the book I created, like this but also the review/s associated with it and currently I can only see the reviews if I navigate to http://localhost:XXXXXX/Review, like here
I hope it makes sense. So, I figured that it was just an amendment to carry out in the book details view, that is to call the model.Review.ReviewText and display it so I went in there and added these last two lines:
<div class="display-label"><!-- added by me, to view review label-->
@Html.DisplayNameFor(model => model.Review.ReviewText)
</div>
<div class="display-field"><!-- added by me, to view review field-->
@Html.DisplayFor(model => model.Review.ReviewText)
</div>
Effectively trying to access the Review details view from the Book details view, but evidently I got it wrong because the Review in @Html.DisplayNameFor(model => model.Review.ReviewText) is underlined and if I hover on it, a tooltip says: "BooksApplication.Models.Book doesn't contain a definition for 'Review' and no extension method 'Review' accepting a first argument of type BooksApplication.Models.Book could be found (are you missing a using directive or an assembly reference?)"
Well, am I? Does it mean that somehow I have to reference the Review object inside the Bood details view? If so how?
Here is the full Book details view with my additions:
@model BooksApplication.Models.Book
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Book</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.BookName)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.BookName)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.ISBN)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.ISBN)
</div>
<div class="display-label"><!-- added by me, to view review label-->
@Html.DisplayNameFor(model => model.Review.ReviewText)
</div>
<div class="display-field"><!-- added by me, to view review field-->
@Html.DisplayFor(model => model.Review.ReviewText)
</div>
</fieldset>
<p>
@Html.ActionLink("Edit", "Edit", new { id=Model.BookID }) |
@Html.ActionLink("Back to List", "Index")
</p>
Any idea?