6 - Examining The Edit Methods and Edit View - Official Microsoft Site
6 - Examining The Edit Methods and Edit View - Official Microsoft Site
6 - Examining The Edit Methods and Edit View - Official Microsoft Site
1 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
Sign In | Join
Search ASP.NET
Home
Overview
Get Started
Downloads
Videos
Web Pages
Samples
Web Forms
Forum
MVC
Solutions
Books
Community
Open Source
Home / MVC / Tutorials / Chapter 8. ASP.NET MVC 4 Beta / Getting Started with ASP.NET MVC 4 / Examining the
Edit Methods and Edit View
Try MVC
controls that
will truly save
you time!
Forums
www.telerik.com/ajax
In this section, you'll examine the generated action methods and views for the movie controller. Then you'll add a
custom search page.
Run the application and browse to the Movies controller by appending /Movies to the URL in the address bar of your
browser. Hold the mouse pointer over an Edit link to see the URL that it links to.
The Edit link was generated by the Html.ActionLink method in the Views\Movies\Index.cshtml view:
@Html.ActionLink("Edit","Edit",new{id=item.ID})
The Html object is a helper that's exposed using a property on the WebViewPage base class. The ActionLink
method of the helper makes it easy to dynamically generate HTML hyperlinks that link to action methods on
controllers. The first argument to the ActionLink method is the link text to render (for example, <a>EditMe</a>).
Powered by
and Umbraco
Follow Us On:
Twitter | Facebook
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
2 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
The generated link shown in the previous image is http://localhost:xxxxx/Movies/Edit/4. The default route (established
in Global.asax.cs) takes the URL pattern {controller}/{action}/{id}. Therefore, ASP.NET translates
http://localhost:xxxxx/Movies/Edit/4 into a request to the Edit action method of the Moviescontroller with the
parameter ID equal to 4.
You can also pass action method parameters using a query string. For example, the URL http://localhost:xxxxx/Movies
/Edit?ID=4 also passes the parameter ID of 4 to the Edit action method of the Movies controller.
Open the Movies controller. The two Edit action methods are shown below.
//
//GET:/Movies/Edit/5
publicActionResultEdit(intid=0)
{
Moviemovie=db.Movies.Find(id);
if(movie==null)
{
returnHttpNotFound();
}
returnView(movie);
}
//
//POST:/Movies/Edit/5
[HttpPost]
publicActionResultEdit(Moviemovie)
{
if(ModelState.IsValid)
{
db.Entry(movie).State=EntityState.Modified;
db.SaveChanges();
returnRedirectToAction("Index");
}
returnView(movie);
}
Notice the second Edit action method is preceded by the HttpPost attribute. This attribute specifies that that
overload of the Edit method can be invoked only for POST requests. You could apply the HttpGet attribute to the
first edit method, but that's not necessary because it's the default. (We'll refer to action methods that are implicitly
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
3 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
Notice how the view template has a @modelMvcMovie.Models.Movie statement at the top of the file this
specifies that the view expects the model for the view template to be of type Movie.
The scaffolded code uses several helper methods to streamline the HTML markup. The Html.LabelFor helper
displays the name of the field ("Title", "ReleaseDate", "Genre", or "Price"). The Html.EditorFor helper displays an
HTML <input> element. The Html.ValidationMessageFor helper displays any validation messages associated with
that property.
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
4 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
Run the application and navigate to the /Movies URL. Click an Edit link. In the browser, view the source for the page.
The HTML for the form element is shown below.
<formaction="/Movies/Edit/4"method="post"><fieldset>
<legend>Movie</legend>
<inputdataval="true"datavalnumber="ThefieldIDmustbeanumber."datavalrequi
<divclass="editorlabel">
<labelfor="Title">Title</label>
</div>
<divclass="editorfield">
<inputclass="textboxsingleline"id="Title"name="Title"type="text"value="Rio
<spanclass="fieldvalidationvalid"datavalmsgfor="Title"datavalmsgreplace="
</div>
<divclass="editorlabel">
<labelfor="ReleaseDate">ReleaseDate</label>
</div>
<divclass="editorfield">
<inputclass="textboxsingleline"dataval="true"datavaldate="ThefieldRelea
<spanclass="fieldvalidationvalid"datavalmsgfor="ReleaseDate"datavalmsgrep
</div>
<divclass="editorlabel">
<labelfor="Genre">Genre</label>
</div>
<divclass="editorfield">
<inputclass="textboxsingleline"id="Genre"name="Genre"type="text"value="Wes
<spanclass="fieldvalidationvalid"datavalmsgfor="Genre"datavalmsgreplace="
</div>
<divclass="editorlabel">
<labelfor="Price">Price</label>
</div>
<divclass="editorfield">
<inputclass="textboxsingleline"dataval="true"datavalnumber="ThefieldPri
<spanclass="fieldvalidationvalid"datavalmsgfor="Price"datavalmsgreplace="
</div>
<p>
<inputtype="submit"value="Save"/>
</p>
</fieldset>
</form>
The <input> elements are in an HTML <form> element whose action attribute is set to post to the /Movies/Edit URL.
The form data will be posted to the server when the Edit button is clicked.
The ASP.NET MVC model binder takes the posted form values and creates a Movie object that's passed as the movie
parameter. The ModelState.IsValid method verifies that the data submitted in the form can be used to modify
(edit or update) a Movie object. If the data is valid, the movie data is saved to the Movies collection of the db
(MovieDBContext instance). The new movie data is saved to the database by calling the SaveChanges method of
MovieDBContext. After saving the data, the code redirects the user to the Index action method of the
MoviesController class, which displays the of movie collection, including the changes just made..
If the posted values aren't valid, they are redisplayed in the form. The Html.ValidationMessageFor helpers in the
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
5 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
Note about locales If you normally work with a locale other than English, see Supporting
ASP.NET MVC Validation with Non-English Locales.
All the HttpGet methods follow a similar pattern. They get a movie object (or list of objects, in the case of Index),
and pass the model to the view. The Create method passes an empty movie object to the Create view. All the
methods that create, edit, delete, or otherwise modify data do so in the HttpPost overload of the method. Modifying
data in an HTTP GET method is a security risk, as described in the blog post entry ASP.NET MVC Tip #46 Dont use
Delete Links because they create Security Holes. Modifying data in a GET method also violates HTTP best practices
and the architectural REST pattern, which specifies that GET requests should not change the state of your application.
In other words, performing a GET operation should be a safe operation that has no side effects and doesn't modify
your persisted data.
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
6 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
if(!String.IsNullOrEmpty(searchString))
{
movies=movies.Where(s=>s.Title.Contains(searchString));
}
returnView(movies);
}
The first line of the SearchIndex method creates the following LINQ query to select the movies:
varmovies=frommindb.Movies
selectm;
The query is defined at this point, but hasn't yet been run against the data store.
If the searchString parameter contains a string, the movies query is modified to filter on the value of the search
string, using the following code:
if(!String.IsNullOrEmpty(searchString))
{
movies=movies.Where(s=>s.Title.Contains(searchString));
}
LINQ queries are not executed when they are defined or when they are modified by calling a method such as Where
or OrderBy. Instead, query execution is deferred, which means that the evaluation of an expression is delayed until its
realized value is actually iterated over or the ToList method is called. In the SearchIndex sample, the query is
executed in the SearchIndex view. For more information about deferred query execution, see Query Execution.
Now you can implement the SearchIndex view that will display the form to the user. Right-click inside the
SearchIndex method and then click Add View. In the Add View dialog box, specify that you're going to pass a
Movie object to the view template as its model class. In the Scaffold template list, choose List, then click Add.
When you click the Add button, the Views\Movies\SearchIndex.cshtml view template is created. Because you selected
List in the Scaffold template list, Visual Web Developer automatically generated (scaffolded) some default content in
the view. The scaffolding created an HTML form. It examined the Movie class and created code to render <label>
elements for each property of the class. The listing below shows the Create view that was generated:
@modelIEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title="SearchIndex";
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
7 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
}
<h2>SearchIndex</h2>
<p>
@Html.ActionLink("CreateNew","Create")
</p>
<table>
<tr>
<th>
Title
</th>
<th>
ReleaseDate
</th>
<th>
Genre
</th>
<th>
Price
</th>
<th></th>
</tr>
@foreach(variteminModel){
<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>
<td>
@Html.ActionLink("Edit","Edit",new{id=item.ID})|
@Html.ActionLink("Details","Details",new{id=item.ID})|
@Html.ActionLink("Delete","Delete",new{id=item.ID})
</td>
</tr>
}
</table>
Run the application and navigate to /Movies/SearchIndex. Append a query string such as ?searchString=ghost to
the URL. The filtered movies are displayed.
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
8 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
If you change the signature of the SearchIndex method to have a parameter named id, the id parameter will match
the {id} placeholder for the default routes set in the Global.asax file.
{controller}/{action}/{id}
You can now pass the search title as route data (a URL segment) instead of as a query string value.
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
9 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
However, you can't expect users to modify the URL every time they want to search for a movie. So now you you'll add
UI to help them filter movies. If you changed the signature of the SearchIndex method to test how to pass the
route-bound ID parameter, change it back so that your SearchIndex method takes a string parameter named
searchString:
publicActionResultSearchIndex(stringsearchString)
{
varmovies=frommindb.Movies
selectm;
if(!String.IsNullOrEmpty(searchString))
{
movies=movies.Where(s=>s.Title.Contains(searchString));
}
returnView(movies);
}
The following example shows a portion of the Views\Movies\SearchIndex.cshtml file with the added filtering markup.
@modelIEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title="SearchIndex";
}
<h2>SearchIndex</h2>
<p>
@Html.ActionLink("CreateNew","Create")
@using(Html.BeginForm()){
<p>Title:@Html.TextBox("SearchString")<br/>
<inputtype="submit"value="Filter"/></p>
}
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
10 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
</p>
The Html.BeginForm helper creates an opening <form> tag. The Html.BeginForm helper causes the form to post to
itself when the user submits the form by clicking the Filter button.
Run the application and try searching for a movie.
There's no HttpPost overload of the SearchIndex method. You don't need it, because the method isn't changing
the state of the application, just filtering data.
You could add the following HttpPostSearchIndexmethod. In that case, the action invoker would match the
HttpPostSearchIndex method, and the HttpPostSearchIndex method would run as shown in the image below.
[HttpPost]
publicstringSearchIndex(FormCollectionfc,stringsearchString)
{
return"<h3>From[HttpPost]SearchIndex:"+searchString+"</h3>";
}
However, even if you add this HttpPostversion of the SearchIndexmethod, there's a limitation in how this has all
been implemented. Imagine that you want to bookmark a particular search or you want to send a link to friends that
they can click in order to see the same filtered list of movies. Notice that the URL for the HTTP POST request is the
same as the URL for the GET request (localhost:xxxxx/Movies/SearchIndex) -- there's no search information in the URL
itself. Right now, the search string information is sent to the server as a form field value. This means you can't capture
that search information to bookmark or send to friends in a URL.
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
11 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
The solution is to use an overload of BeginFormthat specifies that the POST request should add the search
information to the URL and that is should be routed to the HttpGet version of the SearchIndexmethod. Replace the
existing parameterless BeginFormmethod with the following:
@using(Html.BeginForm("SearchIndex","Movies",FormMethod.Get))
Now when you submit a search, the URL contains a search query string. Searching will also go to theHttpGet
SearchIndex action method, even if you have aHttpPostSearchIndex method.
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
12 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
if(string.IsNullOrEmpty(movieGenre))
returnView(movies);
else
{
returnView(movies.Where(x=>x.Genre==movieGenre));
}
}
This version of the SearchIndex method takes an additional parameter, namely movieGenre. The first few lines of
code create a List object to hold movie genres from the database.
The following code is a LINQ query that retrieves all the genres from the database.
varGenreQry=fromdindb.Movies
orderbyd.Genre
selectd.Genre;
The code uses the AddRange method of the generic List collection to add all the distinct genres to the list. (Without
the Distinct modifier, duplicate genres would be added for example, comedy would be added twice in our
sample). The code then stores the list of genres in the ViewBag object.
The following code shows how to check the movieGenre parameter. If it's not empty the code further constrains the
movies query to limit the selected movies to the specified genre.
if(string.IsNullOrEmpty(movieGenre))
returnView(movies);
else
{
returnView(movies.Where(x=>x.Genre==movieGenre));
}
Run the application and browse to /Movies/SearchIndex. Try a search by genre, by movie name, and by both criteria.
In this section you examined the CRUD action methods and views generated by the framework. You created a search
action method and view that let users search by movie title and genre. In the next section, you'll look at how to add a
property to the Movie model and how to add an initializer that will automatically create a test database.
By Rick Anderson, Rick Anderson works as a programmer writer for Microsoft, focusing
on ASP.NET MVC, jQuery and Entity Framework. He enjoys working with the top
contributors in the ASP.NET MVC forum.
Previous
You're Viewing
Next
Comments (1)
Show Comments
20/04/2012 19:41
Examining the Edit Methods and Edit View : Official Microsoft Site
13 de 13
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-m...
20/04/2012 19:41