asp.net mvc applications in c# jim warren, [email protected] compsci 280 s2 2015 enterprise...

26
ASP.NET MVC applications in C# Jim Warren, [email protected] COMPSCI 280 S2 2015 Enterprise Software Development

Upload: domenic-barnett

Post on 12-Jan-2016

215 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

ASP.NET MVC applications in C#Jim Warren, [email protected]

COMPSCI 280 S2 2015Enterprise Software Development

Page 2: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 3: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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 termsof the domain logic)

View – the rendering. What it looks like to the userand the detail of how they interact with the application

Controller – Handles and responds to userinteraction. Uses the model and selects thenext view to offer the user.

COMPSCI 2803

See http://www.asp.net/mvc/tutorials/older-versions/overview/asp-net-mvc-overview

Page 4: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 5: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

MVC application from the template

COMPSCI 2805

Runs at ‘localhost’ served up by the built-in IIS Express local Web

server

Page 6: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

TheController

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(); } }}

Page 7: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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.Model

s at top of HomeController.cs so it

knows the reference to the EmployeesContext

Note that now the ActionResult is returning something

Page 8: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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<Employee> 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; }

}

Page 9: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

OurView

Using the Index.cshtml file we display the datafor the user on the home page

COMPSCI 2809

@model IEnumerable<WebApplication3.Models.Employee>@{ ViewBag.Title = "People"; WebGrid grid = new WebGrid(Model);}<h2>People</h2> @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

Page 10: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

The result

COMPSCI 28010

Page 11: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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 beenconverted to HTML for the browser to consume i.e. a <table> tag for an HTML table, <tr> entries for each

table row, and <td> entries for the table data (each cell) So the ‘server side’ processing accessed the

database and formatted the content as HTML

Handout 02COMPSCI 28011

Page 12: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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;}

Page 13: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 14: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 15: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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 databaseIf 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])

Page 16: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 17: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

Inspecting the HTML All that ‘format’ item lambda

expression boiled down towas a ‘hard coded’ linksaying to access the Editfunction under the Homecontroller 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

Page 18: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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() <div class="form-horizontal"> <h4>Employee</h4> <hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.id)

<div class="form-group"> @Html.LabelFor(model => model.surname, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.surname) @Html.ValidationMessageFor(model => model.surname) </div> </div>

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

Page 19: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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 <label> tag, an <input> tag and a <span> 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

Page 20: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 21: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

The later part of Edit.cshtml

COMPSCI 28021

... <div class="form-group"> @Html.LabelFor(model => model.appointDate, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.appointDate) @Html.ValidationMessageFor(model => model.appointDate) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-default" /> </div> </div> </div>}

<div> @Html.ActionLink("Back to List", "Index")</div>

@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’)

Page 22: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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 @<someHTMLtag> and ends at </someHTMLtag> 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 <text> 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:@<text>@item.appointDate.ToShortDateString()</text>,header:"Date of Appointment"),...

Page 23: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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")

Page 24: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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")]

Page 25: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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

Page 26: ASP.NET MVC applications in C# Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development

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