Saturday, December 1, 2012

5- Accessing Your Model's Data from a Controller (9 Tutorials)




By Rick Anderson|August 28, 2012
In this section, you'll create a new MoviesController class and write code that retrieves the movie data and displays it in the browser using a view template.
Build the application before going on to the next step.
Right-click the Controllers folder and create a new MoviesController controller. The options below will not appear until you build your application. Select the following options:
  • Controller name: MoviesController. (This is the default. )
  • Template: MVC Controller with read/write actions and views, using Entity Framework.
  • Model class: Movie (MvcMovie.Models).
  • Data context class: MovieDBContext (MvcMovie.Models).
  • Views: Razor (CSHTML). (The default.)
AddScaffoldedMovieController
Click Add. Visual Studio Express creates the following files and folders:
  • A MoviesController.cs file in the project's Controllers folder.
  • A Movies folder in the project's Views folder.
  • Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, and Index.cshtml in the new Views\Movies folder.
ASP.NET MVC 4  automatically created the CRUD (create, read, update, and delete) action methods and views for you (the automatic creation of CRUD action methods and views is known as scaffolding). You now have a fully functional web application that lets you create, list, edit, and delete movie entries.
Run the application and browse to the Movies controller by appending /Movies to the URL in the address bar of your browser. Because the application is relying on the default routing (defined in the Global.asax file), the browser request http://localhost:xxxxx/Movies is routed to the default Index action method of the Movies controller. In other words, the browser request http://localhost:xxxxx/Movies is effectively the same as the browser requesthttp://localhost:xxxxx/Movies/Index. The result is an empty list of movies, because you haven't added any yet.

Creating a Movie

Select the Create New link. Enter some details about a movie and then click the Create button.
Clicking the Create button causes the form to be posted to the server, where the movie information is saved in the database. You're then redirected to the /Movies URL, where you can see the newly created movie in the listing.
IndexWhenHarryMet
Create a couple more movie entries. Try the Edit, Details, and Delete links, which are all functional.

Examining the Generated Code

Open the Controllers\MoviesController.cs file and examine the generated Index method. A portion of the movie controller with the Index method is shown below.
public class MoviesController : Controller
{
    private MovieDBContext db = new MovieDBContext();

    //
    // GET: /Movies/

    public ActionResult Index()
    {
        return View(db.Movies.ToList());
    }
The following line from the MoviesController class instantiates a movie database context, as described previously. You can use the movie database context to query, edit, and delete movies.
private MovieDBContext db = new MovieDBContext();
A request to the Movies controller returns all the entries in the Movies table of the movie database and then passes the results to the Index view.

Strongly Typed Models and the @model Keyword

Earlier in this tutorial, you saw how a controller can pass data or objects to a view template using the ViewBagobject. The ViewBag is a dynamic object that provides a convenient late-bound way to pass information to a view.
ASP.NET MVC also provides the ability to pass strongly typed data or objects to a view template. This strongly typed approach enables better compile-time checking of your code and richer IntelliSense in the Visual Studio editor. The scaffolding mechanism in Visual Studio used  this approach with the MoviesController class and view templates when it created the methods and views.
In the Controllers\MoviesController.cs file examine the generated Details method. A portion of the movie controller with the Details method is shown below.
public ActionResult Details(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}
If a  Movie is found, an instance of the Movie model is passed to the Details view. Examine the contents of theViews\Movies\Details.cshtml file.
By including a @model statement at the top of the view template file, you can specify the type of object that the view expects. When you created the movie controller, Visual Studio automatically included the following @modelstatement at the top of the Details.cshtml file:
@model MvcMovie.Models.Movie
This @model directive allows you to access the  movie that the controller passed to the view by using a Model object that's strongly typed. For example, in the Details.cshtml template, the code passes each movie field to theDisplayNameFor and  DisplayFor HTML Helpers with  the strongly typed Model object.  The Create and Edit methods and view templates also pass a movie model object.
Examine the Index.cshtml view template and the Index method in the MoviesController.cs file. Notice how the code creates a List object when it calls the View helper method in the Index action method. The code then passes thisMovies list from the controller to the view:
public ActionResult Index()
{
    return View(db.Movies.ToList());
}
 When you created the movie controller, Visual Studio Express automatically included the following @modelstatement at the top of the Index.cshtml file:
@model IEnumerable<MvcMovie.Models.Movie> 
This @model directive allows you to access the list of movies that the controller passed to the view by using a Modelobject that's strongly typed. For example, in the Index.cshtml template, the code loops through the movies by doing a foreach statement over the strongly typed Model object:
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
         <th>
            @Html.DisplayFor(modelItem => item.Rating)
        </th>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", { id=item.ID })  |
            @Html.ActionLink("Delete", "Delete", { id=item.ID }) 
        </td>
    </tr>
}
Because the Model object is strongly typed (as an IEnumerable<Movie> object), each item object in the loop is typed as Movie. Among other benefits, this means that you get compile-time checking of the code and full IntelliSense support in the code editor:
ModelIntellisene

Working with SQL Server LocalDB

Entity Framework Code First detected that the database connection string that was provided pointed to a Moviesdatabase that didn’t exist yet, so Code First created the database automatically. You can verify that it's been created by looking in the App_Data folder. If you don't see the Movies.mdf file, click the Show All Files button in theSolution Explorer toolbar, click the Refresh button, and then expand the App_Data folder.
Double-click Movies.mdf to open DATABASE EXPLORER, then expand the Tables folder to see the Movies table.
DB_explorer
Note: If  the database explorer doesn't appear, from the TOOLS menu, select Connect to Database, then cancel the Choose Data Source dialog. This will force open the database explorer.

Note: If you are using VWD or Visual Studio 2010 and get an error similar to any of the following following:
  • The database 'C:\Webs\MVC4\MVCMOVIE\MVCMOVIE\APP_DATA\MOVIES.MDF' cannot be opened because it is version 706. This server supports version 655 and earlier. A downgrade path is not supported.
  • "InvalidOperation Exception was unhandled by user code" The supplied SqlConnection does not specify an initial catalog.
You need to install the SQL Server Data Tools and LocalDB. Verify the MovieDBContextconnection string specified on the previous page.
Right-click the Movies table and select Show Table Data to see the data you created.
Right-click the Movies table and select Open Table Definition to see the table structure that Entity Framework Code First created for you.

Notice how the schema of the Movies table maps to the Movie class you created earlier. Entity Framework Code First automatically created this schema for you based on your Movie class.
When you're finished, close the connection by right clicking MovieDBContext and selecting Close Connection. (If you don't close the connection, you might get an error the next time you run the project).
You now have the database and a simple listing page to display content from it. In the next tutorial, we'll examine the rest of the scaffolded code and add a SearchIndex method and a SearchIndex view that lets you search for movies in this database.

4- Adding a Model (9 Tutorials)




By Rick Anderson|August 28, 2012
In this section you'll add some classes for managing movies in a database. These classes will be the "model" part of the ASP.NET MVC application.
You’ll use a .NET Framework data-access technology known as the Entity Framework to define and work with these model classes. The Entity Framework (often referred to as EF) supports a development paradigm called Code First. Code First allows you to create model objects by writing simple classes. (These are also known as POCO classes, from "plain-old CLR objects.") You can then have the database created on the fly from your classes, which enables a very clean and rapid development workflow.

Adding Model Classes

In Solution Explorer, right click the Models folder, select Add, and then select Class.
Enter the class  name "Movie".
Add the following five properties to the Movie class:
public class Movie {
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}
We'll use the Movie class to represent movies in a database. Each instance of a Movie object will correspond to a row within a database table, and each property of the Movie class will map to a column in the table.
In the same file, add the following MovieDBContext class:
 public class MovieDBContext : DbContext {
    public DbSet<Movie> Movies { get; set; } }
The MovieDBContext class represents the Entity Framework movie database context, which handles fetching, storing, and updating Movie class instances in a database. The MovieDBContext derives from the DbContext base class provided by the Entity Framework.
In order to be able to reference DbContext and DbSet, you need to add the following using statement at the top of the file:
using System.Data.Entity;
The complete Movie.cs file is shown below. (Several using statements that are not needed have been removed.)
using System;
using System.Data.Entity;
namespace MvcMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }        
        public DateTime ReleaseDate { get; set; }        
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }

    public class MovieDBContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
    }
}

Creating a Connection String and Working with SQL Server LocalDB

The MovieDBContext class you created handles the task of connecting to the database and mapping Movie objects to database records. One question you might ask, though, is how to specify which database it will connect to. You'll do that by adding connection information in the Web.config file of the application.
Open the application root Web.config file. (Not the Web.config file in the Views folder.) Open the Web.config file outlined in red.
Add the following connection string to the <connectionStrings> element in the Web.config file.
<add name="MovieDBContext" 
   connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True" 
   providerName="System.Data.SqlClient" /> 
The following example shows a portion of the Web.config file with the new connection string added:
<connectionStrings>
  <add name="DefaultConnection" 
       connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcMovie-2012213181139;Integrated Security=true" 
       providerName="System.Data.SqlClient" 
  />      <add name="MovieDBContext" 
       connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True" 
       providerName="System.Data.SqlClient" 
  /> 
</connectionStrings>
This small amount of code and XML is everything you need to write in order to represent and store the movie data in a database. 
Next, you'll build a new MoviesController class that you can use to display the movie data and allow users to create new movie listings.