BIT 286:
Web Applications
Lecture 10: Thursday, February 5, 2015
ASP.Net Form Submission
2
Examining Edit
Form submission
http://www.asp.net/mvc/overview/gettingstarted/introduction/examining-the-edit-methods-and-edit-view
Controller method for first time (non-POST) visit:
3
Examining
Edit:
First Visit:
Controller
Notice how similar this looks to the Details page
// GET: Movies/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
Edit.cshtml
4
Examining
Edit:
First Visit:
the View
The rendered HTML
@model MVCBasics.Models.Movie
@{ ViewBag.Title = "Edit"; }
<h2>Edit</h2>
<h2>Edit</h2>
@using (Html.BeginForm())
<form action="/Movies/Edit/1"
method="post">
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Movie</h4>
<hr />
<input
name="__RequestVerificationToken
" type="hidden"
value="iYr5boxkobMxM9Ad4T9zZ_AcVmdy7Pv6k5Z_mhyIbS
gN3P6uv3G8oheeQ2u_IrBLmdyYyX
bMRs5ECU4wrE_g5s70fRyQP5pKg4T
RC1p_mE1" />
<div class="form-horizontal">
<h4>Movie</h4>
5
XSRF/CSRF
Cross-Site Request Forgery
Good explanation at ASP.Net
Essentially, you visit Web Site #1 and legitimately log in
The browser keeps the authentication info until the web browser process exits
The browser also automatically re-sends the authentication info whenever you visit that
site.
This is very convenient when you’re on Web Site #1
You go to Web Site #2, which attempts to access Web Site #1
E.g., Web Site #2 creates it’s own form, whose action is to submit to Web Site #1
Your browser conveniently re-sends the authentication info along with the form
Web Site #2 can now act as you on Web Site #1
This is the ‘cross site’ part
I’ve heard that this can be done even by ads served to you on pages you trust.
I’d be surprised if Google, MS, etc, would let this happen, but you don’t control which adserving arrangements are used by the websites you visit.
6
XSRF/CSRF
Cross-Site Request Forgery
We can combat this with anti-forgery tokens
Web Site #1 will generate a random number and put it into a hidden field
in the form it sends to you
(This is the anti-forgery token)
Web Site #1 will check (when you post that form back) that the number in
your form matches the one it sent you
This prevents Web Site #2 from making up it’s own form
Because it can’t generate the same random numbers as Web Site #1
7
Edit.cshtml
<div class="form-horizontal">
<h4>Movie</h4>
<hr />
Examining
Edit:
First Visit:
the View
@Html.ValidationSummary(true, "", new {
@class = "text-danger" })
@Html.HiddenFor(model => model.ID)
<div class="form-group">
@Html.LabelFor(model => model.Title,
htmlAttributes: new { @class = "control-label
col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model =>
model.Title, new { htmlAttributes = new {
@class = "form-control" } })
@Html.ValidationMessageFor(model
=> model.Title, "", new { @class = "text-danger"
})
</div>
</div>
The rendered HTML
<input data-val="true" data-valnumber="The field ID must be a
number." data-val-required="The ID
field is required." id="ID" name="ID"
type="hidden" value="1" />
<div class="form-group">
<label class="control-label
col-md-2" for="Title">Title</label>
<div class="col-md-10">
<input class="form-control
text-box single-line" id="Title"
name="Title" type="text"
value="Movie Title #1" />
<span class="fieldvalidation-valid text-danger" datavalmsg-for="Title" data-valmsgreplace="true"></span>
</div>
</div>
Controller method for POST visit:
8
[HttpPost] // Only used for HTTP POST requests; HTTP Get is the default
[ValidateAntiForgeryToken] // checks @Html.AntiForgeryToken() from View
Examining
Edit:
POSTing
the edits:
Controller
public ActionResult Edit([Bind(Include =
"ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
9
Examining Edit:
POSTing the edits
Controller method for POST visit:
[Bind(Include =
"ID,Title,ReleaseDate,Genre,Price")] Movie movie)
public ActionResult Edit(
{ /* Snip */
Include is the list of properties (data fields) to extract from the form
Other fields are left blank in the movie object, even if they’re present in the form
These data fields are filled in for you, automatically, on the movie object.
10
Security Risk: Overposting
Normally you’d never put extra properties in your form….
…but hackers might download & save a copy and add stuff.
For example, let’s say that the ‘Edit User’s Unimportant Account Info’ page normally
just lets you update your firstname, last name, nickname, picture, etc, etc.
But does NOT let you change the password
You can go to that page, select ‘Save As’ in your browser, edit the form locally to also
include a new password for the user, and then submit the form.
If you blindly bound the movie object to ALL fields, and saved the whole object you’d update
the password
The ‘Include’ attribute allows you to only bind to some of the fields
Also a good explanation at MSDN
11
Search
http://www.asp.net/mvc/overview/gettingstarted/introduction/adding-search
12
Tutorial Outline
Adding a search term
‘Search’ Param added to controller method
LINQ query
Important details about when this actually gets executed
Goofy re-use of ‘id’ parameter for a nicer URL
Adding a form
Want to use GET, not POST (GET = retrieve, POST = change DB state)
Decorate form so that it’ll get, not post
Filtering by genre
Querying for the list of genres
Handling a GET’d search
Updating the view to support the above
public ActionResult Index(string searchString)
13
{
var movies = from m in db.Movies
Adding a
parameter
select m;
This is LINQ
This defines, but does
NOT execute the query
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies); This modifies the definition of the query
}
LINQ actually maps to SQL (as
opposed to doing a SELECT * and then
filtering the results in C#
14
My opinion: using ‘id’ as the parameter
This seems goofy – it does produce a nice URL, but the
controller code is kinda ugly (notice how they promptly
renamed the parameter)
15
Adding a New Field
http://www.asp.net/mvc/overview/gettingstarted/introduction/adding-a-new-field
16
Outline
17
Adding Validation
http://www.asp.net/mvc/overview/gettingstarted/introduction/adding-validation
18
Examining the Details and Delete
Methods
http://www.asp.net/mvc/overview/gettingstarted/introduction/examining-the-details-and-delete-methods
19
Topics For Later
Account Management:
http://azure.microsoft.com/en-us/documentation/articles/web-sitesdotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/
Entity Framework:
Foreign keys
How does it handle objects with references to other objects?
JavaScript/jQuery integration?