Lecture 10 PowerPoint

advertisement
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?
Download