Download presentation
Presentation is loading. Please wait.
Published byDomenic Barnett Modified over 9 years ago
1
ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development
2
Today’s learning objectives To be able to work with ASP.NET and the MVC project template for Web applications in VS, including Coordinating model, view and controller for database table access and editing Utilising Razor syntax in.cshtml files for views Employing rudimentary data validation using data annotations COMPSCI 2802
3
The Model-View-Controller approach The MVC architectural pattern separates responsibilities in the application Model – the data (including the connection and mapping to the DBMS) and its integrity constraints (e.g. legal values of variables in terms of the domain logic) View – the rendering. What it looks like to the user and the detail of how they interact with the application Controller – Handles and responds to user interaction. Uses the model and selects the next view to offer the user. COMPSCI 2803 See http://www.asp.net/mvc/tutorials/older-versions/overview/asp-net-mvc-overview
4
An MVC Project in VS Has lots of parts! Controller, Model and View (in alphabetical order in the Solution Explorer) Controller will describe logic for ‘serving up’ Web pages Model defines classes for our database context View defines each screen of the Web page (one.cshtml file for each) Web.config (equivalent to App.config in other templates – thus holds the connection string and related information) Content section include.css (style sheet) for the website Comes pre-built with models for user accounts, and views and controllers for users to register and change their password COMPSCI 2804
5
MVC application from the template COMPSCI 2805 Runs at ‘localhost’ served up by the built-in IIS Express local Web server
6
The Controller The controller has a method of type ActionResult for each webpage in the solution This is run when the application serves up that page The ViewBag is an ‘expando’ object: able to dynamically add attributes to it! ViewBag is a hack for communicating from Controller to View More formal communication is through the return parameter of the ActionResult Handout 01COMPSCI 2806 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace WebApplication1.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult About() { ViewBag.Message = "Your application description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); }
7
Linking in a database Much the same as doing so for a Console application Use the package manager to include EF and MySQL packages Modify Web.config (rather than App.config) with connection string and provider entries Add a class to the Models section of the project, Employee.cs, which defines the data context with the table DbSet and a class definition, Employee, for each row. Edit HomeController.cs to modify the Index (homepage) response: 7 public ActionResult Index() { using (EmployeesContext db = new EmployeesContext()) { int j = db.Employees.Count(); ViewBag.j = String.Format("We have {0} records.",j); var data = db.Employees.ToList(); return View(data); } Need to add using WebApplication3.Models at top of HomeController.cs so it knows the reference to the EmployeesContext Note that now the ActionResult is returning something
8
Our model For this example, let’s say Employee.cs in the Model looks like this: COMPSCI 2808... using System.Data.Entity; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace WebApplication3.Models { public class EmployeesContext : DbContext { public EmployeesContext() : base("MySqlConnection") { } public DbSet Employees { get; set; } } [Table("employee")] public class Employee { [Key] public int id { get; set; } public string surname { get; set; } public string givenNames { get; set; } public DateTime appointDate { get; set; } }
9
Our View Using the Index.cshtml file we display the data for the user on the home page COMPSCI 2809 @model IEnumerable @{ ViewBag.Title = "People"; WebGrid grid = new WebGrid(Model); } People @ViewBag.j @grid.GetHtml(columns: new [] { grid.Column("surname","Last Name"), grid.Column("givenNames","Given Names"), grid.Column("appointDate", "Date of Appointment") }) The @model keyword in Razor says that the data passed to the View will be interpreted as an enumerable list of Employee objects as defined in the Model section of the project Using C# syntax in a Razor code block we instantiate an instance of the WebGrid helper on the Model data Razor functions put the text of element ‘j’ of the ViewBag and the instance of a WebGrid into the body of the HTML. Each WebGrid Column is instantiated on an exact property name of the Employee class from the model
10
The result COMPSCI 28010
11
A closer look If you do ‘Inspect element’ in Chrome on one of the table cells The WebGrid and ViewBag aren’t there Just as the C# code has been converted to CIL for the CLR, the View’s Razor syntax has been converted to HTML for the browser to consume i.e. a tag for an HTML table, entries for each table row, and entries for the table data (each cell) So the ‘server side’ processing accessed the database and formatted the content as HTML Handout 02COMPSCI 28011
12
Making your mark with style We can add a style parameter to the constructor for a grid.Column In the Site.css file (under Content in the Solution Explorer) we can create a corresponding style definition to apply to any element of class surname And the VS intelli-sense greatly assists writing the CSS code! We can also change any HTML tag’s styling for the whole site by editing in Site.css E.g. to make all the rows of any table amber (not depicted in next slide) COMPSCI 28012 @grid.GetHtml(columns: new [] { grid.Column("surname","Last Name",style:"surname"),.surname { font-style: italic; width: 150px; } tr { background-color: #ffe030; }
13
Let’s add an Edit (update) function COMPSCI 28013 Edit button will link to a screen that edits (and saves changes) on the data of that specific record Let’s format the date more reasonably, too
14
Putting the update in the MVC context Making an Edit controller In HomeController.cs we need a new method to ‘catch’ the invocation of the Edit screen COMPSCI 28014 public ActionResult Edit(int id) { ViewBag.Message = String.Format( "Your are editing the record for employee ID #{0}.",id); using (EmployeesContext db = new EmployeesContext()) { Employee emp = db.Employees.Find(id); if (emp == null) return HttpNotFound(); return View(emp); }.Find looks up a record from the dbSet based on its primary key (id was set up as such in MySQL and then this was conveyed to the MVC application by the [Key] annotation in the Model If we picked it off the WebGrid table that we ourselves define it really should be found, but good to handle anyway (e.g. user might edit the URL string, or somebody might’ve deleted it since the user last refreshed their browser screen) We’ll set up the invocation such that the id of the selected record is passed to this handler
15
And we need a second version… In HomeController.cs we need a second signature for the method This version catches the Edit screen when it’s being returned to us filled out / updated by the user COMPSCI 28015 [HttpPost] public ActionResult Edit(Employee emp) { if (ModelState.IsValid) { using (EmployeesContext db = new EmployeesContext()) { db.Entry(emp).State = EntityState.Modified; db.SaveChanges(); } return RedirectToAction("Index"); } return View(emp); } The Edit screen will post back a reference to the whole updated Employee object, emp. If it’s valid (more on that later!) then we save the update to the database If the data was valid, the edit is done so redirect back to the home page; otherwise (there’s some invalid data on the form), present the form to the user again The [HttpPost] decorator signals that this is the one to receive a completed HTML form (the previous one could’ve been annotated as [HttpGet])
16
Invoking the edit controller Putting an ActionLink into the WebGrid To define the column with the Edit link on each employee: grid.Column(header: "Edit", format: (item) => Html.ActionLink("Edit", "Edit", new { id=item.id })) OK, a bit of cryptic Razor syntax here, but note The ‘format’ parameter in the Column constructor just means “put here whatever you want to appear in the data cell on each row” We’re creating an ActionLink (labelled “Edit” and that invokes the Edit handler in our controller) It’s per ‘item’ in the WebGrid (one link for each employee) – ‘item’ is just a magic keyword to indicate the entity on the current row We assign the.id of the current item (i.e. it’s primary key) to ‘id’ – which is the parameter expected by our controller code! COMPSCI 28016
17
Inspecting the HTML All that ‘format’ item lambda expression boiled down to was a ‘hard coded’ link saying to access the Edit function under the Home controller with a parameter equal to the id of the record displayed in that row of the table (i.e. id equal to one in the example shown). COMPSCI 28017
18
Adding the view, Edit.cshtml Actually just right-click Add/View… from the View/Home section in Solution Explorer and it’ll walk you through and autogenerate it VS will autogenerate the real ‘payload’ of the form: COMPSCI 28018 @model WebApplication3.Models.Employee @{ ViewBag.Title = "Edit";... @using (Html.BeginForm()) { @Html.AntiForgeryToken() Employee @Html.ValidationSummary(true) @Html.HiddenFor(model => model.id) @Html.LabelFor(model => model.surname, new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.surname) @Html.ValidationMessageFor(model => model.surname) Specify the Edit template and then select the Employee class from the list of models and this gets filled in – or you could just type it yourself You can, of course, further edit the default. It starts out specifying areas for validation messages along with the labels and the edit boxes Note the primary key, id, is included on the form, but defaults to being a hidden field
19
HTML for the Edit form The ‘data-’ properties aren’t interpreted directly by the browser, but instead are used by jquery.validate.unobtrusive.js to dynamically process user input on the browser and take actions such as having the ‘unobtrusive’ data-val-required message visible when the field is blank COMPSCI 28019 VS generated an HTML form that returns its result to the server by the ‘post’ method and has a hidden verification token for security A straight-forward field like surname gets a tag, an tag and a that’s reserved for data validation messages The primary key went in as a hidden field (we want to have the value, but not to edit it), but VS still mechanically added data validation for it as a required numeric field
20
What about the date? Let’s go back and look at some revision of our Model COMPSCI 28020 [Table(“Employee")] public class Employee { [Key] public int id { get; set; } [Required] public string surname { get; set; } [Display(Name="Given Names")] public string givenNames { get; set; } [Display(Name = "Date of Appointment")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime appointDate { get; set; } } With DateOfBirth, we use the data annotation to say to treat its type as Date (i.e. we aren’t interested in the time-of-day component). The specific “yyyy- MM-dd” format is required so that Chrome will pick up the current value for editing (even though Chrome then shows it in a different culture-sensitive format for the actual editing in the browser!). The [Required] annotation caused VS to include that jQuery validation in the HTML (as per previous slide for id) The Name parameter on [Display] decides the field’s label for the HTML form Cap “MM” for month because lower “mm” is for minutes in DateTime format strings
21
The later part of Edit.cshtml COMPSCI 28021... @Html.LabelFor(model => model.appointDate, new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.appointDate) @Html.ValidationMessageFor(model => model.appointDate) } @Html.ActionLink("Back to List", "Index") @section Scripts { @Scripts.Render("~/bundles/jqueryval") } Actually the Razor for appointDate (and givenNames, too) is really similar to the Razor for surname. The difference is conveyed by the Model Includes the jQuery Link back to home page – essentially canceling the update Form submit button (labelled ‘Save’)
22
A bit more on that appointDate column We don’t want the time on the data of appointment so we can use a Razor expression Again we see the WebGrid’s magic ‘item’ object item is referenced in a format parameter expression ‘format:’ is followed by @ and ends at The content inside gets put in each table row at that column In this case I mainly wanted to put in a Razor expression so I use the inert tag Also note the approach of using name, rather than position, to indicate the optional arguments (format, header) See http://msdn.microsoft.com/en-us/library/dd264739.aspx COMPSCI 28022... grid.Column(format:@ @item.appointDate.ToShortDateString(),header:"Date of Appointment"),...
23
Let’s try some validation attributes Add a salary using phpMyAdmin so we have something numeric Add it to the model Add it to the view on the home page And add it into the edit page view with the 3 @Html. expressions for the label, editor and validation With that we get some ‘free’ validation based on its type COMPSCI 28023 public decimal Salary { get; set; } grid.Column("Salary","Salary")
24
Controlling range and message Let’s add an attribute for salary in the model That gives us an automatic validation message And we can change it if we want to say something different Handout 05COMPSCI 28024 [Range(8000,400000)] [Range(8000,400000,ErrorMessage="This is outside the salary range allowed by the employment agreement")]
25
Controlling range and message (contd.) When we inspect the HTML in Chrome we see the fruits of our labour: There’s heaps more to MVC (and even to Data Annotations!) – plenty of resources are available on the Web COMPSCI 28025 The “0.00” represents the incoming value (in this case it was from the addition of the column in MySQL and not valid to save back!) The data- HTML attribute tags tell me that this is being communicated to the jQuery routines rather than using the HTML5 min and max attributes
26
Conclusion C#/.NET is a powerful language and framework (API and run-time environment) with development supported by the VS IDE Coupled with ADO.NET and EF you can use it to produce database applications Application templates from VS ease the creation of popular application types such as Windows Forms applications and websites (using ASP.NET, for instance with the MVC template) Next class: no lecture; work on your Assignment Then you’re over to Radu for the rest of the course! COMPSCI 28026
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.