BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission
Examining Edit Form submission started/introduction/examining-the-edit-methods-and-edit-view 2
Examining Edit: First Visit: Controller Controller method for first time (non-POST) visit: 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); } 3
Examining Edit: First Visit: the View ViewBag.Title = "Edit"; } (Html.BeginForm()) Movie 4 The rendered HTML Edit Movie
XSRF/CSRF Cross-Site Request Forgery Good explanation at ASP.Net 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 ad- serving arrangements are used by the websites you visit. 5
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 6
Examining Edit: First Visit: the View Edit.cshtml "", new = "text-danger" => => model.Title, htmlAttributes: new = "control-label col-md-2" => model.Title, new { htmlAttributes = new = "form-control" } => model.Title, "", new = "text-danger" }) to List", Scripts } 7 The rendered HTML Title
Examining Edit: POSTing the edits: Controller Controller method for POST visit: [HttpPost] // Only used for HTTP POST requests; HTTP Get is the default [ValidateAntiForgeryToken] // from View 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); } 8
Examining Edit: POSTing the edits Controller method for POST visit: public ActionResult Edit( [ Bind(Include = "ID,Title,ReleaseDate,Genre,Price") ] Movie movie ) { /* 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. 9
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 MSDNgood explanation at MSDN 10
Search started/introduction/adding-search 11
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 12
Adding a parameter public ActionResult Index(string searchString) { var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } return View(movies); } 13 This is LINQ This defines, but does NOT execute the query 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#
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) 14
Adding a New Field started/introduction/adding-a-new-field 15
Outline 16
Adding Validation started/introduction/adding-validation 17
Examining the Details and Delete Methods started/introduction/examining-the-details-and-delete-methods 18
Topics For Later Account Management: dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/ dotnet-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? 19