This tutorial is the final one in a series of a Visual Basic versions of the Introduction to ASP.NET MVC 5 tutorials published on the www.asp.net site. The original series, produced by Scott Guthrie (twitter @scottgu ), Scott Hanselman (twitter: @shanselman ), and Rick Anderson ( @RickAndMSFT ) was written using the C# language. My versions keep as close to the originals as possible, changing only the coding language. The narrative text is largely unchanged from the original and is used with permission from Microsoft.
This tutorial series will teach you the basics of building an ASP.NET MVC 5 Web application using Visual Studio 2013 and Visual Basic. A Visual Studio Express For Web project with VB source code is available to accompany this series which you can download.
The tutorial series comprises 11 sections in total. They cover the basics of web development using the ASP.NET MVC framework and the Entity Framework for data access. They are intended to be followed sequentially as each section builds on the knowledge imparted in the previous sections. The navigation path through the series is as follows:
- Getting Started
- Adding a Controller
- Adding a View
- Adding a Model
- Creating a Connection String and Working with SQL Server LocalDB
- Accessing Your Model's Data from a Controller
- Examining the Edit Methods and Edit View
- Adding Search
- Adding a New Field
- Adding Validation
- Examining the Details and Delete Methods
11. Examining the Details and Delete Methods
In this part of the tutorial, you'll examine the automatically generated Details and Delete methods. Begin by opening the Movie controller and examine the Details method.
Function Details(ByVal id As Integer?) As ActionResult If IsNothing(id) Then Return New HttpStatusCodeResult(HttpStatusCode.BadRequest) End If Dim movie As Movie = db.Movies.Find(id) If IsNothing(movie) Then Return HttpNotFound() End If Return View(movie) End Function
The MVC scaffolding engine that created this action method adds a comment showing a HTTP request that invokes the method. In this case it's a GET request with three URL segments, the Movies controller, the Details method and a ID value.
Code First makes it easy to search for data using the Find method. An important security feature built into the method is that the code verifies that the Find method has found a movie before the code tries to do anything with it. For example, a hacker could introduce errors into the site by changing the URL created by the links fromhttp://localhost:xxxx/Movies/Details/1 to something like http://localhost:xxxx/Movies/Details/12345 (or some other value that doesn't represent an actual movie). If you did not check for a null movie, a null movie would result in a database error.
Examine the Delete and DeleteConfirmed methods.
' GET: /Movies/Delete/5
Function Delete(ByVal id As Integer?) As ActionResult If IsNothing(id) Then Return New HttpStatusCodeResult(HttpStatusCode.BadRequest) End If Dim movie As Movie = db.Movies.Find(id) If IsNothing(movie) Then Return HttpNotFound() End If Return View(movie) End Function ' POST: /Movies/Delete/5 <HttpPost()> <ActionName("Delete")> <ValidateAntiForgeryToken()> Function DeleteConfirmed(ByVal id As Integer) As ActionResult Dim movie As Movie = db.Movies.Find(id) db.Movies.Remove(movie) db.SaveChanges() Return RedirectToAction("Index") End Function
Note that the HTTP Get Delete method doesn't delete the specified movie, it returns a view of the movie where you can submit (HttpPost) the deletion. Performing a delete operation in response to a GET request (or for that matter, performing an edit operation, create operation, or any other operation that changes data) opens up a security hole. For more information about this, see Stephen Walther's blog entry ASP.NET MVC Tip #46 — Don't use Delete Links because they create Security Holes.
The HttpPost method that deletes the data is named DeleteConfirmed to give the HTTP POST method a unique signature or name. The two method signatures are shown below:
' GET: /Movies/Delete/5
Function Delete(ByVal id As Integer?) As ActionResult
' POST: /Movies/Delete/5 <HttpPost()> <ActionName("Delete")> Function DeleteConfirmed(ByVal id As Integer) As ActionResult
The common language runtime (CLR) requires overloaded methods to have a unique parameter signature (same method name but different list of parameters). However, here you need two Delete methods - one for GET and one for POST - that both have the same parameter signature. (They both need to accept a single integer as a parameter.)
To sort this out, you can do a couple of things. One is to give the methods different names. That's what the scaffolding mechanism did in the preceding example. However, this introduces a small problem: ASP.NET maps segments of a URL to action methods by name, and if you rename a method, routing normally wouldn't be able to find that method. The solution is what you see in the example, which is to add the ActionName("Delete") attribute to the DeleteConfirmed method. This effectively performs mapping for the routing system so that a URL that includes /Delete/ for a POST request will find the DeleteConfirmed method.
Another common way to avoid a problem with methods that have identical names and signatures is to artificially change the signature of the POST method to include an unused parameter. For example, some developers add a parameter type FormCollection that is passed to the POST method, and then simply don't use the parameter:
Function DeleteConfirmed(ByVal notUsed As FormCollection, ByVal id As Integer) As ActionResult Dim movie As Movie = db.Movies.Find(id) If movie Is Nothing Then Return HttpNotFound() db.Movies.Remove(movie) db.SaveChanges() Return RedirectToAction("Index")
You now have a complete ASP.NET MVC application that stores data in a local DB database. You can create, read, update, delete, and search for movies.