Вы находитесь на странице: 1из 44

ShevaNguyen

Get Started
Start by running Visual Web Developer 2010 Express (I'll call it "VWD" from now on) and select New Project from the Start Screen. Visual Web Developer is an IDE, or Integrated Developer Environment. Just like you use Microsoft Word to write documents, you'll use an IDE to create applications. There's a toolbar along the top showing various options available to you, as well as the menu you could also have used to Select File | New project.

Creating Your First Application


You can create applications using Visual Basic or Visual C#. For now, Select Visual C# on the left, then pick "ASP.NET MVC 2 Web Application." Name your project "Movies" and click OK.

ASP.NET With MVC 2

Page 1

ShevaNguyen

On the right-hand side is the Solution Explorer showing all the files and folders in your application. The big window in the middle is where you edit your code and spend most of your time. Visual Studio used a default template for the ASP.NET MVC project you just created, so you have a working application right now without doing anything! This is a simple "Hello World! project, and it is a good place to start for our application.

ASP.NET With MVC 2

Page 2

ShevaNguyen

Select the "play" button to the toolbar.

It's a green arrow pointing to the right that will compile your program and start your application in a web browser. NOTE: You can instead press F5 on your keyboard, or select Debug->Start Debugging from the "Debug" menu. This will cause Visual Web Developer to start a development web-server and run our web application (there are no configuration or manual steps required to enable this). It will then launch a browser and configure it to browse the application's home-page. Notice below that the address bar of the browser says localhost, and not something like example.com. That's because localhost always points to your own local computer - which in this case is running the application we just built.

ASP.NET With MVC 2

Page 3

ShevaNguyen

Out of the box this default template gives you two pages to visit and a basic login page. Let's change how this application works and learn a little bit about ASP.NET MVC in the process. Close your browser and lets change some code.

Adding a Controller
MVC stands for Model, View, Controller. MVC is a pattern for developing applications such that each part has a responsibility that is different from another.

Model: The data of your application Views: The template files your application will use to dynamically generate HTML responses. Controllers: Classes that handle incoming URL requests to the application, retrieve model data, and then specify view templates that render a response back to the client

We'll be covering all these concepts in this tutorial and show you how to use them to build an application. Let's create a new controller by right-clicking the controllers folder in the solution Explorer and selecting Add Controller.

ASP.NET With MVC 2

Page 4

ShevaNguyen

Name your new controller "HelloWorldController" and click Add.

Notice in the Solution Explorer on the right that a new file has been created for you called HelloWorldController.cs and that file is now opened in the IDE. Create two new methods that look like this inside of your new public class HelloWorldController. We'll return a string of HTML directly from our controller as an example.

using System.Web.Mvc; namespace Movies.Controllers { public class HelloWorldController : Controller { public string Index() { return "This is my default action..."; } public string Welcome() { return "This is the Welcome action method...";

ASP.NET With MVC 2

Page 5

ShevaNguyen
} }
Your Controller is named HelloWorldController and your new Method is called Index. Run your application again, just as before (click the play button or press F5 to do this). Once your browser has started up, change the path in the address bar to http://localhost:xx/HelloWorld where xx is whatever number your computer has chosen. Now your browser should look like the screenshot below. In our method above we returned a string passed into a method called "Content." We told the system just returns some HTML, and it did! ASP.NET MVC invokes different Controller classes (and different Action methods within them) depending on the incoming URL. The default mapping logic used by ASP.NET MVC uses a format like this to control what code is run: /[Controller]/[ActionName]/[Parameters] The first part of the URL determines the Controller class to execute. So /HelloWorld maps to the HelloWorldController class. The second part of the URL determines the Action method on the class to execute. So /HelloWorld/Index would cause the Index() method of the HelloWorldcontroller class to execute. Notice that we only had to visit /HelloWorld above and the method Index was implied. This is because a method named Index is the default method that will be called on a controller if one is not explicitly specified.

ASP.NET With MVC 2

Page 6

ShevaNguyen
Now, let's visit http://localhost:xx/HelloWorld/Welcome. Now our Welcome Method has executed and returned its HTML string. Again, /[Controller]/[ActionName]/[Parameters] so Controller is HelloWorld and Welcome is the Method in this case. We haven't done Parameters yet.

Let's modify our sample slightly so that we can pass some information in from the URL to our controller, for example like this: /HelloWorld/Welcome?name=Scott&numtimes=4. Change your Welcome method to include two parameters and update it like below. Note that we've used the C# optional parameter feature to indicate that the parameter numTimes should default to 1 if it's not passed in.

public string Welcome(string name, int numTimes = 1) { string message = "Hello " + name + ", NumTimes is: " + numTimes; return "" + Server.HtmlEncode(message) + ""; }
Run your application and visit http://localhost:xx/HelloWorld/Welcome? name=Scott&numtimes=4changing the value of name and numtimes as you like. The system automatically mapped the named parameters from your query string in the address bar to parameters in your method.

ASP.NET With MVC 2

Page 7

ShevaNguyen

In both these examples the controller has been doing all the work, and has been returning HTML directly. Ordinarily we don't want our Controllers returning HTML directly - since that ends up being very cumbersome to code. Instead we'll typically use a separate View template file to help generate the HTML response. Let's look at how we can do this. Close your browser and return to the IDE.

Adding a View
In this section we are going to look at how we can have our HelloWorldController class use a View template file to cleanly encapsulate generating HTML responses back to a client. Let's start by using a View template with our Index method. Our method is called Index and it's in the HelloWorldController. Currently our Index() method returns a string with a message that is hardcoded within the Controller class.

public string Index() { return "<html><body>This is my default action...</body></html>"; }


Let's now change the Index method to instead look like this:

public ActionResult Index() { return View(); }


Let's now add a View template to our project that we can use for our Index() method. To do this, right-click with your mouse somewhere in the middle of the Index method and click Add View...

ASP.NET With MVC 2

Page 8

ShevaNguyen

This will bring up the "Add View" dialog which provides us some options for how we want to create a view template that can be used by our Index method. For now, don't change anything, and just click the Add button.

After you click Add, a new folder and a new file will appear in the Solution Folder, as seen here. I now have a HelloWorld folder under Views, and an Index.aspx file inside that folder.

ASP.NET With MVC 2

Page 9

ShevaNguyen

The new Index file is also already opened and ready for editing. Add some text under the first <h2>Index</h2> like "Hello World."

<h2>Index</h2> Hello world!


Run your application and visit http://localhost:xx/HelloWorld again in your browser. The Index method in our controller in this example didn't do any work, but did call "return View()" which indicated that we wanted to use a view template file to render a response back to the client. Because we did not explicitly specify the name of the view template file to use, ASP.NET MVC defaulted to using the Index.aspx view file within the \Views\HelloWorld folder. Now we see the string we hard-coded in our View.

ASP.NET With MVC 2

Page 10

ShevaNguyen

Looks pretty good. However, notice that the Browser's title says "Index" and the big title on the page says "My MVC Application." Let's change those.

Changing Views and Master Pages


First, let's change the text "My MVC Application." That text is shared and appears on every page. It actually appears in only one place in our code, even though it's on every page in our app. Go to the /Views/Shared folder in the Solution Explorer and open the Site.Master file. This file is called a Master Page and it's the shared "shell" that all our other pages use. Notice some text that says ContentPlaceholder "MainContent" in this file.

<asp:ContentPlaceHolder ID="MainContent" runat="server" />


That placeholder is where all the pages you create will show up, "wrapped" in the master page. Try changing the title, then run your app and visit multiple pages. You'll notice that your one change appears on multiple pages.

<div id="title"> <h1>My MVC Movie Application</h1> </div>


Now every page will have the Primary Heading - that's H1 - of "My MVC Movie Application." That handles the white text at the top there that's shared across all the pages. Here is the Site.Master in its entirety with our changed title:

ASP.NET With MVC 2

Page 11

ShevaNguyen

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DT <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title> <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="page"> <div id="header"> <div id="title"> <h1>My MVC Movie Application</h1> </div> <div id="logindisplay"> <% Html.RenderPartial("LogOnUserControl"); %> </div> <div id="menucontainer"> <ul id="menu"> <li><%: Html.ActionLink("Home", "Index", "Home")%></li> <li><%: Html.ActionLink("About", "About", "Home")%></li> </ul> </div> </div> <div id="main"> <asp:ContentPlaceHolder ID="MainContent" runat="server" /> <div id="footer"> </div> </div> </div> </body> </html>
Now, let's change the title of the Index page. Open /HelloWorld/Index.aspx. There's two places to change. First, the Title that appears in the title of the browser, then the secondary header - that's H2 - as well. I'll make them each slightly different so you can see which bit of code changes which part of the app.

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Movie List </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>My Movie List</h2> Hello World!

ASP.NET With MVC 2

Page 12

ShevaNguyen
</asp:Content>
Run your app and visit /Movies. Notice that the browser title, the primary heading and the secondary headings have changed. It's easy to make big changes in your app with small changes to your view.

Our little bit of "data" (in this case the "Hello World!" message) was hard coded though. We've got V (Views) and we've got C (Controllers), but no M (Model) yet. We'll shortly walk through how create a database and retrieve model data from it.

Passing a ViewModel
Before we go to a database and talk about Models, though, let's first talk about "ViewModels." These are objects that represent what a View template requires to render an HTML response back to a client. They are typically created and passed by a Controller class to a View template, and should only contain the data that the View template requires - and no more. Previously with our HelloWorld sample, our Welcome() action method took a name and a numTimes parameter and output it to the browser. Rather than have the Controller continue to render this response directly,let's instead make a small class to hold that data and then pass it over to a View template to render back the HTML response using it. This way the Controller is concerned with one thing and the View template another enabling us to maintain clean "separation of concerns" within our application.

ASP.NET With MVC 2

Page 13

ShevaNguyen
Return to the HelloWorldController.cs file and add a new "WelcomeViewModel" class and change the Welcome method inside your controller. Here is the complete HelloWorldController.cs with the new class in the same file.

using System.Web.Mvc; namespace Movies.Controllers { public class HelloWorldController : Controller { public ActionResult Index() { return View(); } public ActionResult Welcome(string name, int numTimes = 1) { var viewModel = new WelcomeViewModel { Message = "Hello " + name, NumTimes = numTimes }; return View(viewModel); } public class WelcomeViewModel { public string Message { get; set; } public int NumTimes { get; set; } } } }

Even though it's on multiple lines, our Welcome method is really only two code statements. The first statement packages up our two parameters into a ViewModel object, and the second passes the resulting object onto the View. Now we need a Welcome View template! Right click in the Welcome method and select Add View. This time, we'll check "Create a strongly-typed view" and select our WelcomeViewModel class from the drop down list. This new view will only know about WelcomeViewModels and no other types of objects. NOTE: You'll need to have compiled once after adding your WelcomeViewModel for to show up in the drop down list.

ASP.NET With MVC 2

Page 14

ShevaNguyen
Here's what your Add View dialog should look like. Click the Add

button. Add this code under the <h2> in your new Welcome.aspx. We'll make a loop and say Hello as many times as the user says we should!

<% for(int i=0;i<Model.NumTimes;i++) { %> <%h3><%: Model.Message %></h3> <% } %>


Also, notice while you're typing that because we told this View about the WelcomeViewModel (they are married, remember?) that we get helpful Intellisense each time we reference our Model object as seen in the screenshot below:

ASP.NET With MVC 2

Page 15

ShevaNguyen
Run your application and visit http://localhost:xx/HelloWorld/Welcome? name=Scott&numtimes=4again. Now we're taking data from the URL, it's passed into our Controller automatically, our Controller packages up the data into a ViewModel and passes that object onto our View. The View than displays the data as HTML to the user.

Well, that was a kind of an "M" for Model, but not the database kind. Let's take what we've learned and create a database of Movies.

Creating a Database

In this section we are going to create a new SQL Express database that we'll use to store and retrieve our movie data. From within the Visual Web Developer IDE, select View | Other Windows | Database Explorer. Right click on Data Connection and click Add Connection, or click the icon of the database with a plus sign over it.

ASP.NET With MVC 2

Page 16

ShevaNguyen

In the Connection Properties dialog, enter ".\SQLEXPRESS" for your Server Name, and enter "Movies" as the name for your new database.

ASP.NET With MVC 2

Page 17

ShevaNguyen

Click OK and you'll be asked if you want to create that database. Select yes.

Now you've got an empty database in Database Explore.

ASP.NET With MVC 2

Page 18

ShevaNguyen

Right click on Tables and click Add Table. The Table Designer will appear. Add columns for Id, Title, ReleaseDate, Genre, and Price. Right click on the ID column and click set Primary Key. Here's what my design areas looks like.

Also, select the Id column and under Column Properties below change "Identity Specification" to "Yes."

When you've got it done, click the Save icon in the toolbar or select File | Save from the menu, and name your table "Movie" (singular). We've got a database and a table!

ASP.NET With MVC 2

Page 19

ShevaNguyen

Go back to the Database Explorer and right click the Movie table, then select "Show Table Data." Enter a few movies so our database has some data.

Creating a Model
Now, switch back to the Solution Explorer on the right hand side of the IDE and right-click on the Models folder and select Add | New Item.

ASP.NET With MVC 2

Page 20

ShevaNguyen
We're going to create an Entity Model from our new database. This will add a set of classes to our project that makes it easy for us to query and manipulate the data within our database. Select the Data node on the left-hand side of the dialog, and then select the ADO.NET Entity Data Model item template. Name it Movies.edmx.

Click the "Add" button. This will then launch the "Entity Data Model Wizard". In the new dialog that pops up, select Generate from Database. Since we've just made a database, we'll only need to tell the Entity Framework about our new database and its table. Click Next to save our database connection in our web application's configuration. Now, check the Tables and Movie checkbox and click Finish.

ASP.NET With MVC 2

Page 21

ShevaNguyen

Now we can see our new Movie table in the Entity Framework Designer and access it from code.

ASP.NET With MVC 2

Page 22

ShevaNguyen

On the design surface you can see a "Movie" class. This class maps to the "Movie" table in our database, and each property within it maps to a column with the table. Each instance of a "Movie" class will correspond to a row within the "Movie" table. If you don't like the default naming and mapping conventions used by the Entity Framework, you can use the Entity Framework designer to change or customize them. For this application we'll use the defaults and just save the file as-is. Now, let's work with some real data!

Accessing your Model's Data from a Controller


In this section we are going to create a new MoviesController class, and write some code that retrieves our Movie data and displays it back to the browser using a View template. Right click on the Controllers folder and make a new MoviesController.

ASP.NET With MVC 2

Page 23

ShevaNguyen

This will create a new "MoviesController.cs" file underneath our \Controllers folder within our project. Let's update the MovieController to retrieve the list of movies from our newly populated database.

?
using using using using System; System.Linq; System.Web.Mvc; Movies.Models;

namespace Movies.Controllers { public class MoviesController : Controller { MoviesEntities db = new MoviesEntities(); public ActionResult Index() { var movies = from m in db.Movies where m.ReleaseDate > new DateTime(1984, 6, 1) select m; return View(movies.ToList()); } } }

We are performing a LINQ query so that we only retrieve movies released after the summer of 1984. We'll need a View template to render this list of movies back, so right-click in the method and select Add View to create it. Within the Add View dialog we'll indicate that we are passing a List<Movies.Models.Movie> to our View template. Unlike the previous times we used the Add View dialog and chose to create an "Empty" template, this time we'll indicate that we want Visual Studio to automatically "scaffold" a view template for us with some default content. We'll do this by selecting the "List" item within the View content dropdown menu. Remember, when you have a created a new class you'll need to compile your application for it to show up in the Add View Dialog.

ASP.NET With MVC 2

Page 24

ShevaNguyen

Click add and the system will automatically generate the code for a View for us that displays our list of movies. This is a good time to change the <h2> heading to something like "My Movie List" like we did earlier with the Hello World view.

ASP.NET With MVC 2

Page 25

ShevaNguyen

Run your application and visit /Movies in the address bar. Now we've retrieved data from the database using a basic query inside the Controller and returned the data to a View that knows about Movies. That View then spins through the list of Movies and creates a table of data for us.

ASP.NET With MVC 2

Page 26

ShevaNguyen

We wont be implementing Edit, Details and Delete functionality with this application - so we dont need the default links that the scaffold template created for us. Open up the /Movies/Index.aspx file and remove them. Here is the source code for what our updated View template should look like once we make these changes:

?
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Movie List </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>My Movie List</h2> <table> <tr> <th>Title</th> <th>ReleaseDate</th> <th>Genre</th> <th>Rating</th> <th>Price</th> </tr> <% foreach (var item in Model) { %> <tr> <td><%: item.Title %></td> <td><%: String.Format("{0:g}", item.ReleaseDate) %></td> <td><%: item.Genre %></td>

<%@ Page Title="" Language="C#" MasterPageFile="/Views/Shared/Site.Master" Inherits="Sys

ASP.NET With MVC 2

Page 27

ShevaNguyen
<td><%: item.Rating %></td> <td><%: String.Format("{0:F}", item.Price) %></td> </tr> <% } %> </table> <p> <%: Html.ActionLink("Create New", "Create") %> </p> </asp:Content>
It's creating links that we won't need, so we'll delete them for this example. We will keep our Create New link though, as that's next! Here's what our app looks like with that column removed.

We now have a simple listing of our movie data. However, if we click the "Create New" link, we'll get an error as it's not hooked up! Let's implement a Create Action method and enable a user to enter new movies in our database.

Adding a Create Method and Create View


In this section we are going to implement the support necessary to enable users to create new movies in our database. We'll do this by implementing the /Movies/Create URL action. Implementing the /Movies/Create URL is a two step process. When a user first visits the /Movies/Create URL we want to show them an HTML form that they can fill out to enter a new

ASP.NET With MVC 2

Page 28

ShevaNguyen
movie. Then, when the user submits the form and posts the data back to the server, we want to retrieve the posted contents and save it into our database. We'll implement these two steps within two Create() methods within our MoviesController class. One method will show the <form> that the user should fill out to create a new movie. The second method will handle processing the posted data when the user submits the <form> back to the server, and save a new Movie within our database. Below is the code we'll add to our MoviesController class to implement this:

?
public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Movie newMovie) { if (ModelState.IsValid) { db.AddToMovies(newMovie); db.SaveChanges(); return RedirectToAction("Index"); } else { } }

return View(newMovie);

The above code contains all of the code that we'll need within our Controller. Let's now implement the Create View template that we'll use to display a form to the user. We'll right click in the first Create method and select "Add View" to create the view template for our Movie form. We'll select that we are going to pass the view template a "Movie" as its view data class, and indicate that we want to "scaffold" a "Create" template.

ASP.NET With MVC 2

Page 29

ShevaNguyen

After you click the Add button, \Movies\Create.aspx View template will be created for you. Because we selected "Create" from the "view content" dropdown, the Add View dialog automatically "scaffolded" some default content for us. The scaffolding created an HTML <form>, a place for validation error messages to go, and since scaffolding knows about Movies, it created Label and Fields for each property of our class.

?
<% using (Html.BeginForm()) {%> <%: Html.ValidationSummary(true) %> <fieldset> <legend>Fields</legend> <div class="editor-label"> <%: Html.LabelFor(model => model.Id) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Id) %> <%: Html.ValidationMessageFor(model => model.Id) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Title) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Title) %> <%: Html.ValidationMessageFor(model => model.Title) %>

ASP.NET With MVC 2

Page 30

ShevaNguyen
</div> <div class="editor-label"> <%: Html.LabelFor(model => model.ReleaseDate) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.ReleaseDate) %> <%: Html.ValidationMessageFor(model => model.ReleaseDate) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Genre) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Genre) %> <%: Html.ValidationMessageFor(model => model.Genre) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Price) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Price) %> <%: Html.ValidationMessageFor(model => model.Price) %> </div> <p>

<input type="submit" value="Create" /> </p> </fieldset> <% } %>


Since our database automatically gives a Movie an ID, let's remove those fields that reference model.Id from our Create View. Remove the 7 lines after <legend>Fields</legend> as they show the ID field that we don't want. Let's now create a new movie and add it to the database. We'll do this by running the application again and visit the "/Movies" URL and click the "Create" link to add a new Movie.

ASP.NET With MVC 2

Page 31

ShevaNguyen

When we click the Create button, we'll be posting back (via HTTP POST) the data on this form to the /Movies/Create method that we just created. Just like when the system automatically took the "numTimes" and "name " parameter out of the URL and mapped them to parameters on a method earlier, the system will automatically take the Form Fields from a POST and map them to an object. In this case, values from fields in HTML like "ReleaseDate" and "Title" will automatically be put into the correct properties of a new instance of a Movie. Let's look at the second Create method from our MoviesController again. Notice how it takes a "Movie" object as an argument:

?
[HttpPost] public ActionResult Create(Movie newMovie)

ASP.NET With MVC 2

Page 32

ShevaNguyen
{ if (ModelState.IsValid) { db.AddToMovies(newMovie); db.SaveChanges(); return RedirectToAction("Index"); } else { } }

return View(newMovie);

This Movie object was then passed to the [HttpPost] version of our Create action method, and we saved it in the database and then redirected the user back to the Index() action method which will show the saved result in the movie list:

We aren't checking if our movies are correct, though, and the database won't allow us to save a movie with no Title. It'd be nice if we could tell the user that before the database threw an error. We'll do this next by adding validation support to our application.

Adding Validation to the Model


ASP.NET With MVC 2
Page 33

ShevaNguyen
In this section we are going to implement the support necessary to enable input validation within our application. We'll ensure that our database content is always correct, and provide helpful error messages to end users when they try and enter Movie data which is not valid. Well begin by adding a little validation logic to the Movie class. Right click on the Model folder and select Add Class. Name your class Movie. When we created the Movie Entity Model earlier, the IDE created a Movie class. In fact, part of the Movie class can be in one file and part in another. This is called a Partial Class. We're going to extend the Movie class from another file. We'll create a partial movie class that points to a "buddy class" with some attributes that will give validation hints to the system. We'll mark the Title and Price as Required, and also insist that the Price be within a certain range. Right click the Models folder and select Add Class. Name your class Movie and Click the OK button. Here's what our partial Movie class looks like.

using System.ComponentModel.DataAnnotations; namespace Movies.Models { [MetadataType(typeof(MovieMetadata))] public partial class Movie { class MovieMetadata { [Required(ErrorMessage="Titles are required")] public string Title { get; set; } [Required(ErrorMessage="The Price is required.")] [Range(5,100,ErrorMessage ="Movies cost between $5 and $100.")] public decimal Price { get; set; } } }
Re-Run your application and try to enter a movie with a price over 100. You'll get an error after you've submitted the form. The error is caught on the server side and occurs after the Form is POSTed. Notice how ASP.NET MVC's built-in HTML helpers were smart enough to display the error message and maintain the values for us within the textbox elements:

ASP.NET With MVC 2

Page 34

ShevaNguyen

This works great, but it'd be nice if we could tell the user on the client-side, immediately, before the server gets involved. Let's enable some client-side validation with JavaScript.

Adding Client-Side Validation


Since our Movie class already has some validation attributes, we'll just need to add a few JavaScript files to our Create.aspx View template and add a line of code to enable client-side validation to take place. From within VWD go our Views/Movie folder and open up Create.aspx. Open up the Scripts folder in the Solution Explorer and drag the following three scripts to within the <head> tag.

MicrosoftAjax.js MicrosoftMvcValidation.js

ASP.NET With MVC 2

Page 35

ShevaNguyen
You want these script files to appear in this order.

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>


Also, add this single line above the Html.BeginForm:

<% Html.EnableClientValidation(); %>


Here's the code shown within the IDE.

Run your application and visit /Movies/Create again, and click Create without entering any data. The error messages appear immediately without the page flash that we associate with sending data all the way back to the server. This is because ASP.NET MVC is now validating the input on both the client (using JavaScript) and on the server.

ASP.NET With MVC 2

Page 36

ShevaNguyen

This is looking good! Let's now add one additional column to the database.

Adding a Column to the Model


In this section we are going to walk through how we can make changes to the schema of our database, and handle the changes within our application. Let's add a "Rating" Colum to the Movie table. Go back to the IDE and click the Database Explorer. Right click the Movie table and select Open Table Definition. Add a "Rating" column as seen below. Since we don't have any Ratings now, the column can allow nulls. Click Save.

ASP.NET With MVC 2

Page 37

ShevaNguyen

Next, return to the Solution Explorer and open up the Movies.edmx file (which is in the \Models folder). Right click on the design surface (the white area) and select Update Model from Database.

This will launch the "Update Wizard". Click the Refresh tab within it and click Finish. Our Movie model class will then be updated with the new column.

ASP.NET With MVC 2

Page 38

ShevaNguyen

After clicking Finish, you can see the new Rating Column has been added to the Movie Entity in our model.

We've added a column in the database model, but the Views don't know about it.

ASP.NET With MVC 2

Page 39

ShevaNguyen
Update Views with Model Changes
There are a few ways we could update our view templates to reflect the new Rating column. Since we created these Views by generating them via the Add View dialog, we could delete them and recreate them again. However, typically people will have already made modifications to their View templates from the initial scaffolded generation and will want to add or delete fields manually, just as we did with the ID field for Create. Open up the \Views\Movies\Index.aspx template and add a <th>Rating</th> to the head of the Movie table. I added mine after Genre. Then, in the same column position but lower down, add a line to output our new Rating.

?
<td> <%: item.Rating %> </td>
Our final Index.aspx template will look like this:

?
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Movie List </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>My Movie List</h2> <table> <tr> <th>Id</th> <th>Title</th> <th>ReleaseDate</th> <th>Genre</th> <th>Rating</th> <th>Price</th> </tr> <% foreach (var item in Model) { %> <tr> <td><%: item.Id %></td> <td><%: item.Title %></td> <td><%: String.Format("{0:g}", item.ReleaseDate) %></td> <td><%: item.Genre %></td> <td><%: item.Rating %></td> <td><%: String.Format("{0:F}", item.Price) %></td> </tr> <% } %> </table> <p> <%: Html.ActionLink("Create New", "Create") %> </p> </asp:Content>
Let's then open up the \Views\Movies\Create.aspx template and add a Label and Textbox for our new Rating property:

<%@ Page Title="" Language="C#" MasterPageFile="/Views/Shared/Site.Master" Inherits="Syst

<div class="editor-label"> <%: Html.LabelFor(model => model.Rating) %>

ASP.NET With MVC 2

Page 40

ShevaNguyen
</div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Rating)%> <%: Html.ValidationMessageFor(model => model.Rating)%> </div>
Our final Create.aspx template will look like this, and let's change our browser's title and secondary <h2> title to something like "Create a Movie" while we're in here!

<%@ Page Title="" Language="C#" MasterPageFile="/Views/Shared/Site.Master" Inherits="Syst <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Create a Movie </asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></scrip <h2>Create a Movie</h2> <% Html.EnableClientValidation(); %> <% using (Html.BeginForm()) {%> <%: Html.ValidationSummary(true) %> <fieldset> <legend>Fields</legend> <div class="editor-label"> <%: Html.LabelFor(model => model.Title) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Title) %> <%: Html.ValidationMessageFor(model => model.Title) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.ReleaseDate) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.ReleaseDate) %> <%: Html.ValidationMessageFor(model => model.ReleaseDate) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Genre) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Genre) %> <%: Html.ValidationMessageFor(model => model.Genre) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Rating) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Rating)%> <%: Html.ValidationMessageFor(model => model.Rating)%> </div>

ASP.NET With MVC 2

Page 41

ShevaNguyen
<div class="editor-label"> <%: Html.LabelFor(model => model.Price) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Price) %> <%: Html.ValidationMessageFor(model => model.Price) %> </div> <p> <input type="submit" value="Create" /> </p> </fieldset> <% } %> <div> <%: Html.ActionLink("Back to List", "Index") %> </div> </asp:Content>
Run your app and now you've got a new field in the database that's been added to the Create page. Add a new Movie - this time with a Rating - and click Create.

ASP.NET With MVC 2

Page 42

ShevaNguyen

After you click Create, you're sent to the Index page where you new Movie is listed with the new Rating Column in the database

ASP.NET With MVC 2

Page 43

ShevaNguyen

This basic tutorial got you started making Controllers, associating them with Views and passing around hard-coded data. Then we created and designed a Database and put some data it in. We retrieved the data from the database and displayed it in an HTML table. Then we added a Create form that let the user add data to the database themselves from within the Web Application. We added validation, then made the validation use JavaScript on the client-side. Finally, we changed the database to include a new column of data, then updated our two pages to create and display this new data

--------------------------------- At The End ---------------------------------

ASP.NET With MVC 2

Page 44

Вам также может понравиться