asp.net mvc et web api -...

97
1 Asp.Net MVC et WEB API I. MVC ......................................................................................................................................................... 4 1. « FROM SCRATCH » - DEMARRER AVEC UN PROJET ASP.NET VIDE................................................................................. 4 2. ROUTES ............................................................................................................................................................. 8 a. RouteConfig ................................................................................................................................................ 8 b. Attribut Route ............................................................................................................................................. 9 c. Area........................................................................................................................................................... 10 d. Récupérer les informations de route ........................................................................................................ 11 3. CONTROLEURS................................................................................................................................................... 12 a. « Action Result » ....................................................................................................................................... 12 b. Index ......................................................................................................................................................... 12 c. Détails ....................................................................................................................................................... 13 d. Create ....................................................................................................................................................... 13 e. Edit ............................................................................................................................................................ 14 f. Delete ........................................................................................................................................................ 14 g. Actions asynchrones ................................................................................................................................. 15 h. Actions Selectors ....................................................................................................................................... 15 i. Action filters ......................................................................................................................................... 16 j. Contrôleur Mvc comme Web Service ........................................................................................................ 17 4. VIEWS ............................................................................................................................................................. 20 a. _ViewStart ........................................................................................................................................... 22 b. _Layout (Master page/ Page de disposition) ....................................................................................... 22 @RenderSection() ...................................................................................................................................................... 23 c. Définir le modèle de la vue .................................................................................................................. 23 d. Html Helpers ........................................................................................................................................ 23 e. Code expressions pour insérer du C# dans le HTML .......................................................................... 25 Code blocks ................................................................................................................................................................ 25 f. Scripts .................................................................................................................................................. 25 g. SelectList .............................................................................................................................................. 26 h. Moteur de vue Aspx ............................................................................................................................. 26 i. Ajax Helpers ......................................................................................................................................... 26 Ajax Form ................................................................................................................................................................... 27 Ajax ActionLink........................................................................................................................................................... 28 5. VALIDATION...................................................................................................................................................... 29 a. Data Annotations................................................................................................................................. 29 b. IValidatableObject ............................................................................................................................... 31 c. Modifier le style des erreurs ................................................................................................................ 32 d. Validation côté « Client » avec jQuery Validation Plugin ................................................................... 32 6. SECURITE..................................................................................................................................................... 33 a. Windows (Intranet) .............................................................................................................................. 33 b. « From scratch » - Sécurité « Forms » avec un projet Asp.Net vide .................................................... 34 Packages NuGet ......................................................................................................................................................... 34 Préparation ................................................................................................................................................................ 34 « IdentityConfig » (dossier « App_Start ») ............................................................................................................ 34 ApplicationUser..................................................................................................................................................... 36 Classe partielle « Startup » ................................................................................................................................... 37 Base de données ................................................................................................................................................... 38

Upload: ngobao

Post on 23-Nov-2018

226 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

1

Asp.Net MVC et WEB API

I. MVC ......................................................................................................................................................... 4

1. « FROM SCRATCH » - DEMARRER AVEC UN PROJET ASP.NET VIDE................................................................................. 4

2. ROUTES ............................................................................................................................................................. 8

a. RouteConfig ................................................................................................................................................ 8

b. Attribut Route ............................................................................................................................................. 9

c. Area ........................................................................................................................................................... 10

d. Récupérer les informations de route ........................................................................................................ 11

3. CONTROLEURS ................................................................................................................................................... 12

a. « Action Result » ....................................................................................................................................... 12

b. Index ......................................................................................................................................................... 12

c. Détails ....................................................................................................................................................... 13

d. Create ....................................................................................................................................................... 13

e. Edit ............................................................................................................................................................ 14

f. Delete ........................................................................................................................................................ 14

g. Actions asynchrones ................................................................................................................................. 15

h. Actions Selectors ....................................................................................................................................... 15

i. Action filters ......................................................................................................................................... 16

j. Contrôleur Mvc comme Web Service ........................................................................................................ 17

4. VIEWS ............................................................................................................................................................. 20

a. _ViewStart ........................................................................................................................................... 22

b. _Layout (Master page/ Page de disposition) ....................................................................................... 22 @RenderSection() ...................................................................................................................................................... 23

c. Définir le modèle de la vue .................................................................................................................. 23

d. Html Helpers ........................................................................................................................................ 23

e. Code expressions pour insérer du C# dans le HTML .......................................................................... 25 Code blocks ................................................................................................................................................................ 25

f. Scripts .................................................................................................................................................. 25

g. SelectList .............................................................................................................................................. 26

h. Moteur de vue Aspx ............................................................................................................................. 26

i. Ajax Helpers ......................................................................................................................................... 26 Ajax Form ................................................................................................................................................................... 27 Ajax ActionLink........................................................................................................................................................... 28

5. VALIDATION ...................................................................................................................................................... 29

a. Data Annotations ................................................................................................................................. 29

b. IValidatableObject ............................................................................................................................... 31

c. Modifier le style des erreurs ................................................................................................................ 32

d. Validation côté « Client » avec jQuery Validation Plugin ................................................................... 32

6. SECURITE ..................................................................................................................................................... 33

a. Windows (Intranet) .............................................................................................................................. 33

b. « From scratch » - Sécurité « Forms » avec un projet Asp.Net vide .................................................... 34 Packages NuGet ......................................................................................................................................................... 34 Préparation ................................................................................................................................................................ 34

« IdentityConfig » (dossier « App_Start ») ............................................................................................................ 34 ApplicationUser..................................................................................................................................................... 36 Classe partielle « Startup » ................................................................................................................................... 37 Base de données ................................................................................................................................................... 38

Page 2: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

2

2

Personnalisation des pages ................................................................................................................................... 38 Contrôleurs et ViewModels .................................................................................................................................. 39

Inscription (register) .................................................................................................................................................. 40 Connexion (Login) ...................................................................................................................................................... 43 Connexion «externe » avec Facebook, Google, Twitter ............................................................................................ 48

Facebook ............................................................................................................................................................... 48 Google ................................................................................................................................................................... 50 Twitter................................................................................................................................................................... 52 Code supplémentaire ............................................................................................................................................ 52

c. Autorisations (attribut « Authorize ») .................................................................................................. 55 ValidateAntiForgeryToken ......................................................................................................................................... 56 AntiXSS ....................................................................................................................................................................... 57

d. SSL ........................................................................................................................................................ 57

e. Projet Visual Studio 2012 ..................................................................................................................... 58 InitializeSimpleMembership et WebSecurity ............................................................................................................. 58 SimpleRoleProvider et SimpleMembershipProvider ................................................................................................. 59 Register ...................................................................................................................................................................... 60 Login .......................................................................................................................................................................... 60

7. LOCALISATION .............................................................................................................................................. 61

Dates et Monnaies........................................................................................................................................ 61

Resources ...................................................................................................................................................... 62

8. LESS ........................................................................................................................................................... 63

9. DEPENDENCY INJECTION (DI) .......................................................................................................................... 63 Avec Ninject ............................................................................................................................................................... 63

10. UPGRADE ................................................................................................................................................ 64

II. WEB API ................................................................................................................................................. 65

1. Web Api config ..................................................................................................................................... 65

2. Contrôleur Web Api ............................................................................................................................. 65 a. HTTP Status codes ............................................................................................................................................ 65 b. Ajout d’un contrôleur Web Api ........................................................................................................................ 65 c. Contrôleur Web API avec IhttpActionResult .................................................................................................... 66 d. Contrôleur Web API avec HttpResponseMessage ............................................................................................ 68

3. Attribut “Route” ................................................................................................................................... 71

4. Injection de dépendances .................................................................................................................... 71 Avec Ninject ............................................................................................................................................................... 71

5. Projet Client ......................................................................................................................................... 72 a. dataService JavaScript ...................................................................................................................................... 72 b. HttpClient ......................................................................................................................................................... 73

6. Cors ...................................................................................................................................................... 75

7. Formatters pour le « Mapping » .......................................................................................................... 76

8. OData................................................................................................................................................... 76

9. Authentification Web Api .................................................................................................................... 77

10. MongoDB ........................................................................................................................................ 82 a. Installation de MongoDB C# driver .................................................................................................................. 82 b. Service WEB ..................................................................................................................................................... 83

III. BOOTSTRAP ........................................................................................................................................... 86

1. INSTALLATION ET THEMES ............................................................................................................................... 86

2. GRID SYSTEM ............................................................................................................................................... 87

a. Cacher une colonne selon une résolution ............................................................................................ 87

b. Décalage de colonnes avec « offset » .................................................................................................. 88

Page 3: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

3

3

c. Image flottante .................................................................................................................................... 88

3. BASES ......................................................................................................................................................... 88

a. Typographie ......................................................................................................................................... 88

b. Boutons, groupes de boutons et dropdowns ....................................................................................... 89

c. Icones ................................................................................................................................................... 90

d. Formulaires, listes, et tables ................................................................................................................ 90 « input-group » .......................................................................................................................................................... 90

e. Navbar desktop et mobile .................................................................................................................... 90

f. Header et breadcrumb ......................................................................................................................... 91

g. Pagination............................................................................................................................................ 91

h. Well ...................................................................................................................................................... 92

i. Panels .................................................................................................................................................. 92

PLUGINS .............................................................................................................................................................. 92

a. Collapse et accordéon .......................................................................................................................... 92

b. Boite de dialogue ................................................................................................................................. 93

c. Alert ..................................................................................................................................................... 93

d. Tab ....................................................................................................................................................... 94

e. Tooltip .................................................................................................................................................. 94

f. Caroussel.............................................................................................................................................. 95

Page 4: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

4

4

I. MVC

1. « From scratch » - Démarrer avec un projet Asp.Net vide 1. Créer un projet Asp.Net vide

2. Installer « Asp.Net Mvc 5 » avec les packages NuGet

3. Ajouter « RouteConfig » dans un dossier « App_Start »

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace MvcFromScratch { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } }

Vue (Affiche les données)

Vue partielle

« content » (texte, xml)

JSON

Redirection

etc.

Contrôleur Modèles/

Données Va chercher

les données

Définition des routes de

l’application. Ici la route par

défaut dirigeant vers l’action

« Index » du contrôleur « Home »

Action

Result

ROUTES

« http://... / » « contrôleur »/« action »/« id »

Page 5: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

5

5

4. Ajouter fichier de configuration de l’application « Global.asax»

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace MvcFromScratch { public class Global : System.Web.HttpApplication { protected void Application_Start() { RouteConfig.RegisterRoutes(RouteTable.Routes); } } }

5. Ajouter un contrôleur « Home » dans un dossier « Controllers »

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcFromScratch.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return Content("Bonjour!"); } } }

Projet minimum

Enregistrement des routes

définies dans le fichier

« RouteConfig »

L’ « action result » ici est

une chaine de caractère.

Cela affichera juste ce

message dans une page

Page 6: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

6

6

Avec Vue en « action result »

public ActionResult Index() { return View(); }

Vues :

« _ViewStart.cshtml » hérite de « StartPage » (System.Web.Mvc) sert à définir la master

page « par défaut » utilisée par toutes les pages de contenu.

Toutes les autres pages héritent de « WebViewPage » (_Lauout, Index, etc.)

2 possibilités :

Soit définir en haut de chaque vue la page dont elle hérite

Exemple « _ViewStart.cshtml »

@inherits System.Web.WebPages.StartPage @{ Layout = "~/Views/Shared/_Layout.cshtml"; }

« _Layout.cshtml » la master page (ou page de disposition)

@inherits System.Web.Mvc.WebViewPage <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> </head> <body style="background:red;"> <div> @RenderBody() </div> </body> </html>

Page 7: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

7

7

Soit on crée un fichier de configuration « Web.config » pour le dossier des vues

« Views » pour ne pas avoir à définir sur chaque page <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> </sectionGroup> </configSections> <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="MvcFromScratch" /> </namespaces> </pages> </system.web.webPages.razor> </configuration> Ainsi on peut simplifier les pages… par exemple « _ViewStart.cshtml »

@{ Layout = "~/Views/Shared/_Layout.cshtml"; }

Projet minium avec vues et master page

On supprime l’héritage en

haut des pages

_Layout.cshtml la master page

_ViewStart.cshtml permet de définir la master page à appliquer par

défaut aux pages de contenu

Les vues sont rangées dans un dossier portant le nom de leur

contrôleur

Page 8: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

8

8

2. Routes

a. RouteConfig

Définir les routes de l’application dans « RouteConfig » (dossier « App_Start »)

public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { action = "Index", controller="People", id = UrlParameter.Optional } ); } }

Créer une seconde route public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Ma route", url: "personal/{myparameter}", defaults: new { controller = "Home", action = "Personal", myparameter = "Bonjour" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }

Dans le contrôleur « Home », on ajoute l’action pour cette route public class HomeController : Controller { // code retiré public ActionResult Personal(string myparameter) { return Content(myparameter); } }

On place la route au-dessus de

la route « par défaut »

La route

« http://.../personal/ »

Page 9: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

9

9

Dans le cas où on aurait pas défini de paramètre de route routes.MapRoute( name: "Ma route", url: "personal", defaults: new { controller = "Home", action = "Personal"} );

… On pourrait quand même passer un paramètre à l’action (code inchangé) en le nommant

b. Attribut Route public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapMvcAttributeRoutes(); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }

Utilisation : Dans le contrôleur « Home » [Route("personal")] public ActionResult Personal() { return Content("Route ok!"); }

Si on veut ajouter des paramètres, les mettre entre accolades [Route("personal/{message}")] public ActionResult Personal(string message) { return Content(message); }

Permettre l’utilisation de

l’attribut « route »

.Attention de bien mettre

avant la route par défaut

Paramètre passé

Renvoie par défaut la valeur définie dans

« RouteConfig »

Page 10: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

10

10

c. Area

Il peut être intéressant de découper les gros projets en « Areas »

Exemple

public class MusicAreaRegistration : AreaRegistration { public override string AreaName { get { return "Music"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Music_default", "Music/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional }, namespaces: new[] { "AreaDemo.Areas.Music.Controllers" } ); } }

« Global.asax »

AreaRegistration.RegisterAllAreas();

Page 11: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

11

11

d. Récupérer les informations de route

public class HomeController : Controller { // code retiré public ActionResult Personal() { var controller = RouteData.Values["controller"]; // var action = RouteData.Values["action"]; // var id = RouteData.Values["id"]; // var result = string.Format("{0}, {1}, {2}", controller, action, id); return Content(result); } }

Exemple depuis une vue on crée un lien

@Html.ActionLink("A envoyer!", "Personal", new { controller = "Home", id = 10 }) L’adresse du lien « http://localhost:7211/Home/Personal/10 »

Depuis une action du contrôleur

public ActionResult Index() { return RedirectToAction("Personal", "Home", new { id = 100 }); }

action contrôleu

r

paramètre

Page 12: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

12

12

3. Contrôleurs

a. « Action Result »

ViewResult : une page complète

public ActionResult Index() { IEnumerable<Person> people = _peopleRepository.GetAll(); return View(people); } PartialViewResult : une section de page

return PartialView("_people", people);

ContentResult : texte, xml return Content("Bonjour!");

JsonResult : objet JSON return Json(people,JsonRequestBehavior.AllowGet);

RedirectToRouteResult : redirection vers une autre action return RedirectToRoute(new { controller = "Home", action = "index" }); return RedirectToAction("Index");

JavaScriptResult return JavaScript("alert('Bonjour!')"); + EmptyResult, FileResult, HttpUnauthorizedResult, etc.

b. Index public ActionResult Index() { IEnumerable<Person> people = _peopleRepository.GetAll(); return View(people); }

Page 13: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

13

13

c. Détails public ActionResult Details(int id) { Person person = _peopleRepository.GetOne(id); if (person == null) return HttpNotFound("Personne non trouvée"); return View(person); }

d. Create public ActionResult Create() { Person newPerson = new Person(); return View(newPerson); } [HttpPost] public ActionResult Create(Person person) { if (ModelState.IsValid) { _peopleRepository.Add(person); return RedirectToAction("Index"); } return View(person); }

On crée dans un premier temps un

nouvel élément que l’on affiche

dans la vue « Create »

on ajoute le nouvel élément

(post). S’il y a des erreurs de

validation on redirige pour que

l’utilisateur corrige

Page 14: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

14

14

e. Edit public ActionResult Edit(int id = 0) { Person person = _peopleRepository.GetOne(id); if (person == null) return HttpNotFound("Personne non trouvée"); return View(person); } [HttpPost] public ActionResult Edit(Person person) { if (ModelState.IsValid) { _peopleRepository.Update(person); return RedirectToAction("Index"); } return View(person); }

f. Delete public ActionResult Delete(int id = 0) { Person person = _peopleRepository.GetOne(id); if (person == null) return HttpNotFound("Personne non trouvée"); return View(person); } [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { _peopleRepository.Delete(id); return RedirectToAction("Index"); }

On récupère l’élément à

modifier que l’on affiche

dans la vue « Edit »

on sauve les modifications

apportées s’il n’y a pas

d’erreurs

On récupère l’élément à

supprimer que l’on affiche

Si l’utilisateur confirme la

suppression, on supprime

réellement l’élément.

Page 15: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

15

15

g. Actions asynchrones public async Task<ActionResult> Index()

{

IEnumerable<Person> people = await _peopleRepository.GetAllAsync(); return View(people); }

h. Actions Selectors

Attribut « HttpGet » par défaut, inutile de l’indiquer

Attribut « HttpPost »

ViewBag permet d’afficher des messages passés depuis le contrôleur.

Exemple

Dans le contrôleur

public ActionResult Index() { ViewBag.Message1 = "Bonjour!"; ViewBag.Message2 = "Aurevoir :x"; return View(); }

Dans la vue

<h3>@ViewBag.Message1</h3> <h3>@ViewBag.Message2</h3>

Page 16: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

16

16

i. Action filters

Ce sont des attributs que l’on place au-dessus d’une action ou du contrôleur.

Authorization filter (Attribut « Authorize »)

Autorize et ValidateAntiForgeryToken Voir Authentification

ValidateInput Accepte toutes les entrées (même s’il y a des balises, ce qui peut représenter un

code malveillant)

[HttpPost] [ValidateInput(true)] public ActionResult Edit(Person person) { // } Il est possible également d’utiliser l’attribut « AllowHtml » pour une propriété du modèle

[AllowHtml] public string LastName { get; set; }

Action filter (faire hériter de « ActionFilterAttribute » et override « OnActionExecuting »,

« OnActionExecuted »)

Result filter : exemple « OutputCache » (met en cache 60 secondes)

//[ChildActionOnly] [OutputCache(Duration=60)] public ActionResult Index() { IEnumerable<Person> people = _peopleRepository.GetAll(); return View(people); }

Exception fliter

Pour gérer une « unhandled exception ». Exemple redirige vers une vue

[HandleError(View="Errors")] public ActionResult Edit(Person person) { Pour voir la page erreur comme l’utilisateur (et non page d’erreur « coté serveur »)

Page 17: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

17

17

j. Contrôleur Mvc comme Web Service

Même si utiliser un contrôleur Web Api est tout indiqué aujourd’hui, cela reste possible

d’utiliser un contrôleur Mvc comme web service.

public class PeopleWebServiceController : Controller { private IPeopleRepository _peopleRepository; public PeopleWebServiceController() : this(new FakePeopleRepository()) { } public PeopleWebServiceController(IPeopleRepository peopleRepository) { this._peopleRepository = peopleRepository; } public ActionResult Index() { IEnumerable<Person> people = _peopleRepository.GetAll(); return Json(people, JsonRequestBehavior.AllowGet); } public ActionResult Details(int id) { Person person = _peopleRepository.GetOne(id); if (person == null) return HttpNotFound(); return Json(person, JsonRequestBehavior.AllowGet); } [HttpPost] public void Create(Person person) { _peopleRepository.Add(person); } [HttpPost] public void Edit(Person person) { _peopleRepository.Update(person); } public void Delete(int id) { _peopleRepository.Delete(id); } }

Json.net (documentation) Sérialization d’un objet

string json = JsonConvert.SerializeObject(person);

Désérialization de JSon JsonConvert.DeserializeObject<Person>(resultContent)

Page 18: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

18

18

Tests avec Fiddler

Index et détails

Ajout

Edition

Suppression

Page 19: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

19

19

Projet Client

Utilisation de HttpClient(System.Net.Http) et de Json.Net (Projet WinRT, Wpf)

public class PeopleService { string urlBase = "http://localhost:15089/peoplewebservice/"; public async Task<Person[]> GetAll() { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync(urlBase); string resultContent = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Person[]>(resultContent); } } public async Task<Person> GetOne(int personID) { using (HttpClient client = new HttpClient()) { HttpResponseMessage result = await client.GetAsync(string.Format("{0}/details/{1}", urlBase, personID)); string resultContent = await result.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Person>(resultContent); } } public async void Add(Person person) { using (HttpClient client = new HttpClient()) { string json = JsonConvert.SerializeObject(person); HttpResponseMessage response = await client.PostAsync(string.Format("{0}/create", urlBase), new StringContent(json, Encoding.UTF8, "application/json")); string resultContent = await response.Content.ReadAsStringAsync(); person = JsonConvert.DeserializeObject<Person>(resultContent); } } public async void Update(Person person) { using (HttpClient client = new HttpClient()) { string json = JsonConvert.SerializeObject(person); HttpResponseMessage response = await client.PutAsync(string.Format("{0}/edit", urlBase), new StringContent(json, Encoding.UTF8, "application/json")); string resultContent = await response.Content.ReadAsStringAsync(); person = JsonConvert.DeserializeObject<Person>(resultContent); } } public async void Delete(int personID) { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.DeleteAsync(string.Format("{0}/delete/{1}", urlBase, personID)); response.EnsureSuccessStatusCode(); } } }

Page 20: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

20

20

4. Views

Il existe 2 moteurs de vues : Razor (*.cshtml) et Aspx (*.aspx)

(Le code des contrôleurs ne diffère pas selon le moteur de vue utilisé)

On peut ajouter une vue :

- Depuis le menu contextuel sur une action d’un contrôleur - Sur le répertoire « Views »

Un dossier de vues par contrôleur

Vue Action Index Index Details Details Create Create Edit Edit Delete Delete …

Un dossier de vues par

contrôleur

Contrôleurs

Page 21: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

21

21

Création d’une vue

Vue partielle

Utilisation : Dans la vue

@Html.Partial("_people", Model)

Contrôleur

return PartialView("_people", people);

Choix du modèle de la vue

Vue partielle. On a l’habitude

de nommer les vues

partielles avec « _ » pour les

différencier rapidement

Page 22: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

22

22

a. _ViewStart

Définir la master page par défaut pour les pages de contenu @{ Layout = "~/Views/Shared/_Layout.cshtml"; }

Pour affecter une autre master page à une vue particulière. Définir la master page en haut de la

vue @{ Layout = "~/Views/Shared/_MyLayout.cshtml"; }

b. _Layout (Master page/ Page de disposition)

(Dossier « Shared »)

Contient tout le HTML commun pour les pages ainsi que RenderBody() pour afficher le contenu

des vues et RenderSection(). On peut créer plusieurs master pages.

Exemple de master page <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <header> <h1>Titre</h1> <nav> <ul> <li>@Html.ActionLink("Accueil", "Index")</li> <li>@Html.ActionLink("A propos", "Aboutus")</li> <li>@Html.ActionLink("Contact", "Contact")</li> </ul> </nav> </header> <div> @RenderBody() </div> <footer></footer> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>

Page 23: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

23

23

@RenderSection()

Permet de définir ses propres sections

Exemple Dans la master page (_layout.cshtml) <div> @if (IsSectionDefined("header")) { @RenderSection("header", required: false); } else { <h3>Header par défaut</h3> } </div> <div class="container"> @RenderBody() </div> Dans une vue @section header { <h3>Ma section header</h3> }

c. Définir le modèle de la vue

Exemple

@model MvcOverview.Models.Person Ou pour une vue Liste @model IEnumerable<MvcOverview.Models.Person>

Avec @using @using MvcOverview.Models @model IEnumerable<Person>

d. Html Helpers

Documentation

Lien

(Avec paramètre ici)

@Html.ActionLink("Editer", "Edit", new { id = item.Id }) Action

Insère le résultat de l’action (ici la vue « Create »)

<p>@Html.Action("Create")</p> @url

<a href="@Url.Action("Index","Home")"><img src="~/Images/logo.png" /></a>

Page 24: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

24

24

Formulaire

Html Fortement typé BeginForm EndForm TextArea TextBox Label CheckBox RadioButton ListBox

CheckBoxFor EditorFor ListBoxFor RadioButtonFor TextAreaFor ValidationMessage ValidationSummary

Vue en consultation (List, Details)

Label (DisplayNameFor) @Html.DisplayNameFor(model => model.FirstName) Affiche la valeur (DisplayFor) @Html.DisplayFor(model => model.FirstName)

Vue avec édition (Create, Edit)

Label @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label

col-md-2" }) … puis champ en edition avec valeur et Validation @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })

@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger"

})

Dans un formulaire @using (Html.BeginForm()) { @Html.ValidationSummary(true) @Html.AntiForgeryToken() @* code ici *@ } Exemple de formulaire @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>People</legend> <div class="editor-label"> @Html.LabelFor(model => model.FirstName) </div> <div class="editor-field"> @Html.EditorFor(model => model.FirstName) @Html.ValidationMessageFor(model => model.FirstName) </div> @* etc. *@ <p> <input type="submit" value="Valider" /> </p> </fieldset> } <div> @Html.ActionLink("Retour", "Index") </div>

Page 25: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

25

25

e. Code expressions pour insérer du C# dans le HTML

Valeur <p>there are @Model.Count() people.</p>

@@ Permet de ne pas confondre avec du C#

Plusieurs instructions @(item.FirstName + ' ' + item.LastName)

Code blocks

Permet par exemple de créer ses variables et les réutiliser

@{ ViewBag.Title = "Index"; var count = Model.Count(); } <p>there are @count people.</p>

Dans les blocs @if ,@foreach … @foreach (var item in Model) { @: var fullName = string.Format("{0}, {1}", item.LastName, item.FirstName); <td> code block : @fullName </td> </tr> }

Insérer du texte dans un code block

<text>Mon texte</text> @:Mon texte Fonction

@DoSomething() @helper DoSomething() { <span>Bonjour depuis la fonction!</span> }

f. Scripts @section Scripts { <script> $(function () { }); </script> }

Exécute la fonction

Page 26: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

26

26

g. SelectList

Pour afficher une liste avec sélection de l’élément.

…source, « champ de sélection », « champ affiché »,selectedValue

@Html.DropDownListFor(modelItem => item.CategoryID,new

SelectList(Model.Categories,"CategoryID","CategoryName",item.CategoryID))

public class ClientViewModel

{

public IList<ClientModel> Clients { get; set; }

public IList<CategoryModel> Categories { get; set; }

}

On peut aussi définir « SelectList » dans le modèle

h. Moteur de vue Aspx

Un mot sur le moteur de vue Aspx.Les pages ont pour extension *.aspx.

On utilise : <%= %> ou <%: %> pour encadrer une instruction Ex :<%= Html.ActionLink("Home","Index") %>

<% %> pour encadrer les blocs de code (exemple avec une variable ou if/foreach)

i. Ajax Helpers

Ajax options

Url url requested Confirm Message de confirmation affiché dans une

boite de dialogue OnBegin,OnComplete,OnSuccess,OnFailure LoadingElementId L’élément affiché pendant le « chargement »

(exemple un spinner) LoadingElementDuration Durée d’affichage de l’élément de chargement UpdateTargetId Element modifé InsertionMode Replace,InsertAfter,InsertBefore

Unobtrusive Ajax

Page 27: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

27

27

Ajax Form

Le vue @model IEnumerable<string> @{ ViewBag.Title = "Home Page"; } @* Ajax form *@ @using (Ajax.BeginForm("Index", new AjaxOptions { HttpMethod = "get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "cityList", LoadingElementDuration = 500, LoadingElementId = "progress" })) { <input type="search" name="searchTerm" /> <input type="submit" value="Submit" /> } @* spinner *@ <div id="progress" style="display:none"> <img src="~/Images/spinner.gif" /> </div> @* partial view *@ @Html.Partial("_cities", Model) @* unobstrusive Ajax *@ @section scripts { <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>

} La vue partielle @model IEnumerable<string> <div id="cityList"> <table> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item) </td> </tr> } </table>

</div>

Page 28: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

28

28

Le contrôleur public class HomeController : Controller { private static readonly string[] cities = { "Shanghai", "Moscou", "Seoul", "Beijing", "Tokyo", "Mexico", "New York", "Londres","Bangkok","Caire", "Rio de Janeiro", "Saint Petersburg", "Los Angeles", "Yokohama","Berlin", "Madrid", "Chicago", "Houston", "Philadelphie", "Phoenix","San Diego", "Dallas", "Indianapolis", "San Francisco", "Austin", "Columbus", "Fort Worth", "Charlotte", "Detroit","Boston", "Washington", "Denver","Portland", "Las Vegas","Atlanta", "Colorado Springs", "Omaha", "Miami", "Cleveland", "Minneapolis","Honolulu", "Buffalo", "Lincoln", "Orlando", "Chandler", "Laredo", "Madison", "Reno","Irving", "Toronto", "Montreal", "Vancouver", "Calgary", "Edmonton", "Quebec", }; public ActionResult Index(string searchTerm = null) { if (Request.IsAjaxRequest()) if (searchTerm != null) { var result = cities.Where(c => c.ToLower().StartsWith(searchTerm.ToLower())); return PartialView("_cities", result); } return View(cities); }

}

Ajax ActionLink

@Ajax.ActionLink("City List", "Index", new AjaxOptions { UpdateTargetId = "cityList",

HttpMethod = "get" })

Page 29: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

29

29

5. Validation Pour bien faire il faut une validation côté client et une validation à la mise à jour côté serveur.

a. Data Annotations

Documentation

On distingue :

Les attributs servant à mettre en forme

Display

DisplayFormat

DisplayColumn pour la clé étrangère

DataType permet de mettre en forme (exemple password)

Les attributs de validation:

Required

StringLength

MaxLength

MinLength

Compare

Range

RegularExpression

Attribut Key

Namespace « Schema »

Table

Column

ComplexType

DatabaseGeneratded

InverseProperty

ForeignKey

NotMapped

Page 30: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

30

30

Custom Attribute

Exemple création d’un attribut permettant de valider Twitter

public class TwitterAttribute : ValidationAttribute { private string pattern = "^@([A-Za-z0-9_]+)"; protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value != null) { var valueAsString = value.ToString(); if (!Regex.IsMatch(valueAsString, "^@([A-Za-z0-9_]+)")) { return new ValidationResult("Enter a valide twitter"); } } return ValidationResult.Success; } private readonly int _maxWords; }

Page 31: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

31

31

Utilisation

[Display(Name = "Twitter : ")] [Twitter] public string Twitter { get; set; }

Contrôleur

[HttpPost] public ActionResult Create(Person person) { ValidatePerson(person); if (ModelState.IsValid) { _peopleRepository.Add(person); return RedirectToAction("Index"); } return View(person); } private void ValidatePerson(Person person) { string twitter = person.Twitter; if (string.IsNullOrWhiteSpace(twitter)) return; if (!Regex.IsMatch(twitter, "^@([A-Za-z0-9_]+)")) ModelState.AddModelError("Twitter", "Twitter invalide."); }

b. IValidatableObject

Le modèle peut implémenter IValidatableObject, la méthode « Validate » sera automatiquement

appelée …

public class Person : IValidatableObject { // … properties public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (!Regex.IsMatch(Twitter, "^@([A-Za-z0-9_]+)")) { yield return new ValidationResult("Enter a valide twitter", new[] { "Twitter" }); } } }

Vérifie si le formulaire

ne contient pas

d’erreurs

on ajoute une erreur au

modèle

Page 32: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

32

32

c. Modifier le style des erreurs .input-validation-error { border: 1px solid #e64343; box-shadow: 0 0 2px 0 rgba(230, 67, 67, 0.4); } .input-validation-error:focus { background: #fcecec; border: 1px solid #e64343; box-shadow: 0 0 2px 0 rgba(230, 67, 67, 0.4); } .validationMessage { color: Red; }

d. Validation côté « Client » avec jQuery Validation Plugin

http://jqueryvalidation.org/

Référence <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Exemple pour afficher un message d’erreur <div> @Html.LabelFor(model => model.FirstName) @Html.TextBoxFor(model => model.FirstName) @Html.ValidationMessageFor(model => model.FirstName) </div>

Page 33: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

33

33

6. Sécurité Articles sur la sécurité Asp.Net

a. Windows (Intranet)

<p>Bonjour, @User.Identity.Name!</p>

<configuration> <system.web> <compilation debug="true" targetFramework="4.5.1" /> <httpRuntime targetFramework="4.5.1" /> <authentication mode="Windows" /> </system.web> </configuration>

Page 34: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

34

34

b. « From scratch » - Sécurité « Forms » avec un projet Asp.Net vide

Packages NuGet

Besoin de :

EntityFramework

AspNet.Identity.Core

Identity.EntityFramework

Identity.Owin

Microsoft.Owin.Host.SystemWeb (méthodes d’extension)

Depuis la console du gestionnaire de package PM> Install-Package EntityFramework PM> Install-Package Microsoft.AspNet.Identity.Core PM> Install-Package Microsoft.AspNet.Identity.EntityFramework PM> Install-Package Microsoft.AspNet.Identity.Owin PM> Install-Package Microsoft.Owin.Host.SystemWeb

+ Si on utilise Facebook, Google, Twitter, etc. pour une connexion externe.

PM> install-package Microsoft.Owin.Security.Facebook PM> install-package Microsoft.Owin.Security.Google PM> install-package Microsoft.Owin.Security.Twitter

Préparation

« IdentityConfig » (dossier « App_Start ») using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using System.Web; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security; using MvcFromScratch.Models; using System.Net.Mail; namespace MvcFromScratch { public class EmailService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { var client = new SmtpClient("smtp.xyz.fr"); client.Send("[email protected]", message.Destination, message.Subject, message.Body); return Task.FromResult(0); } } public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Connectez votre service SMS ici pour envoyer un message texte.

Page 35: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

35

35

return Task.FromResult(0); } } public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store) { } public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) { var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); manager.UserValidator = new UserValidator<ApplicationUser>(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5; manager.RegisterTwoFactorProvider("Code téléphonique ", new PhoneNumberTokenProvider<ApplicationUser> { MessageFormat = "Votre code de sécurité est {0}" }); manager.RegisterTwoFactorProvider("Code d'e-mail", new EmailTokenProvider<ApplicationUser> { Subject = "Code de sécurité", BodyFormat = "Votre code de sécurité est {0}" }); manager.EmailService = new EmailService(); manager.SmsService = new SmsService(); var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } } // Configurer le gestionnaire de connexion d'application

Configuration du nom d’utilisateur

(autoriser les chiffres dans les

noms ? email uniques ?)

Configuration du mot de passe

(longueur min. ? lettre ou digit

requis ? upper case requis ? )

Verrouillage après 5 erreurs

d’authentification

Configuration de ApplicationUserManager

Page 36: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

36

36

public class ApplicationSignInManager : SignInManager<ApplicationUser, string> { public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) { return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); } public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) { return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); } } }

ApplicationUser

Dans le dossier « Models »

using System.Data.Entity; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; namespace MvcFromScratch.Models { // consultez http://go.microsoft.com/fwlink/?LinkID=317594 public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } } public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } } }

Page 37: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

37

37

Classe partielle « Startup »

Dans le dossier « App_Start »

using System; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.Google; using Owin; using MvcFromScratch.Models; namespace MvcFromScratch { public partial class Startup { // rendez-vous sur http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); // Autoriser l’application à utiliser un cookie app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { // Permet à l'application de valider le timbre de sécurité OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) } }); app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); app.UseFacebookAuthentication( appId: "475813752569575", appSecret: "123456789abcdefg "); app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "903536450598-ps3vsah291ef6iekkqtqflc2d0g746hj.apps.googleusercontent.com", ClientSecret = "123456789abcdefg" }); // Supprimer les commentaires //app.UseTwitterAuthentication( // consumerKey: "", // consumerSecret: ""); } } }

Connexions

« externes »

Page 38: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

38

38

A la racine du projet

using Microsoft.Owin; using Owin; [assembly: OwinStartupAttribute(typeof(MvcFromScratch.Startup))] namespace MvcFromScratch { public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); } } }

Base de données

Créer le dossier spécial « App_Data » dans lequel la base de données sera créée

Chaine de connexion dans « Web.config »

<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Identity.mdf;Initial Catalog=Identity;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>

Personnalisation des pages

Dans une vue partielle(_LoginPartial) ou la master page (_Layout)

@using Microsoft.AspNet.Identity @if (Request.IsAuthenticated) { <h2>Bonjour @User.Identity.GetUserName() !</h2> @Html.ActionLink("Se déconnecter", "Logoff", "Account") } else { <li>@Html.ActionLink("S’inscrire", "Register", "Account")</li> <li>@Html.ActionLink("Se connecter", "Login", "Account")</li> }

On nomme la base qui sera créée « Identity »

par exemple

« AspNetUsers » Contient tous les utilisateurs

(email, userName, passwordhash,etc.).

Pas de mot de passe pour les utilisateurs

connectés en « externe » (facebook, etc.) , mais

ajout de l’Id dans « AspNetUserLogins »

On pourrait également vérifier si

l’utilisateur appartient à un rôle,

pour donner accès à la gestion du

site par exemple

Page 39: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

39

39

Contrôleurs et ViewModels

Créer « AccountController » dans le dossier « Controllers »

using MvcFromScratch.Models; using System; using System.Globalization; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin.Security; namespace MvcFromScratch.Controllers { [Authorize] public class AccountController : Controller { private ApplicationSignInManager _signInManager; private ApplicationUserManager _userManager; public ApplicationSignInManager SignInManager { get { return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); } private set { _signInManager = value; } } public ApplicationUserManager UserManager { get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); } private set { _userManager = value; } } private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } private IAuthenticationManager AuthenticationManager { Get { return HttpContext.GetOwinContext().Authentication; } } private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) ModelState.AddModelError("", error); } } }

Créer « AccountViewModels » qui contiendra tous les ViewModels dans le dossier

« Models »

Page 40: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

40

40

Inscription (register)

« AccountController »

// GET: /Account/Register [AllowAnonymous] public ActionResult Register() { return View(); } // POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { // Avec confirmation string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); await UserManager.SendEmailAsync(user.Id, "Confirmez votre compte", "Confirmez votre compte en cliquant <a href=\"" + callbackUrl + "\">ici</a>"); ViewBag.Message = "Un email vous a été envoyé afin de confirmer votre compte."; return View("Info"); // Sans confirmation // await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); //return RedirectToAction("Index", "Home"); } AddErrors(result); } return View(model); } // GET: /Account/ConfirmEmail [AllowAnonymous] public async Task<ActionResult> ConfirmEmail(string userId, string code) { if (userId == null || code == null) { return View("Error"); } var result = await UserManager.ConfirmEmailAsync(userId, code); return View(result.Succeeded ? "ConfirmEmail" : "Error"); }

on envoie un email de demande

de confirmation

Sans demande de confirmation, on connecte

directement l’utilisateur après l’inscription et le

redirige vers la page d’accueil

Réaffiche le formulaire en cas d’erreurs de validation

Page 41: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

41

41

ViewModels

public class RegisterViewModel { [Required] [EmailAddress] [Display(Name = "Courrier électronique")] public string Email { get; set; } [Required] [StringLength(100, ErrorMessage = "La chaîne {0} doit comporter au moins {2} caractères.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Mot de passe")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirmer le mot de passe ")] [Compare("Password", ErrorMessage = "Le mot de passe et le mot de passe de confirmation ne correspondent pas.")] public string ConfirmPassword { get; set; } } Vues:

- Register (pour s’inscrire), ConfirmEmail (affichée après que l’utilisateur ait cliqué sur le lien

de confirmation de l’email envoyé) …Vues dans le dossier « Account » des vues « Views »

- Info, Error (dossier « Shared »)

Register

@model MvcFromScratch.Models.RegisterViewModel @{ ViewBag.Title = "S’inscrire"; } <h2>@ViewBag.Title.</h2> @using (Html.BeginForm("Register", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <h4>Créer un nouveau compte.</h4> <hr /> @Html.ValidationSummary() <div> @Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email) </div> <div> @Html.LabelFor(m => m.Password) @Html.PasswordFor(m => m.Password) </div> <div> @Html.LabelFor(m => m.ConfirmPassword) @Html.PasswordFor(m => m.ConfirmPassword) </div> <div> <input type="submit" class="btn btn-default" value="Inscription" /> </div> }

Page 42: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

42

42

ConfirmEmail

@{ ViewBag.Title = "Confirmation de l'e-mail"; } <h2>@ViewBag.Title.</h2> <div> <p> Merci d'avoir confirmé votre e-mail. Veuillez @Html.ActionLink("Cliquer ici pour vous connecter", "Login", "Account") </p> </div> Info

@{ ViewBag.Title = "Info"; } <h2>@ViewBag.Title.</h2> <h3>@ViewBag.Message</h3> Error

@{ ViewBag.Title = "Erreur"; } <h1>Erreur</h1> <p>@ViewBag.ErrorMessage</p>

Page 43: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

43

43

Connexion (Login)

« AccountController »

// GET: /Account/Login [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } var user = await UserManager.FindByNameAsync(model.Email); if (user != null) { if (!await UserManager.IsEmailConfirmedAsync(user.Id)) { ViewBag.ErrorMessage = "Vous devez confirmer votre email."; return View("Error"); } } var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "Tentative de connexion non valide."); return View(model); } } private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } return RedirectToAction("Index", "Home"); } // POST: /Account/LogOff [HttpPost] [ValidateAntiForgeryToken] public ActionResult LogOff() { AuthenticationManager.SignOut(); return RedirectToAction("Index", "Home"); }

Vérifie que l’utilisateur a

bien validé son compte avec

l’email

Vérifie que le formulaire ne

comporte pas d’erreurs

Déconnexion

Page 44: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

44

44

Mot de passe oublié

// GET: /Account/ForgotPassword [AllowAnonymous] public ActionResult ForgotPassword() { return View(); } // POST: /Account/ForgotPassword [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model) { if (ModelState.IsValid) { var user = await UserManager.FindByNameAsync(model.Email); if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id))) { return View("ForgotPasswordConfirmation"); } var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); await UserManager.SendEmailAsync(user.Id, "Reset Password", "Cliquez sur ce lien pour réinitaliser votre mot de passe : " + callbackUrl); ViewBag.Link = callbackUrl; return View("ForgotPasswordConfirmation"); } return View(model); } // GET: /Account/ResetPassword [AllowAnonymous] public ActionResult ResetPassword(string code) { var id = Request.QueryString["userid"]; var model = new ResetPasswordViewModel() { Id = id, Code = code }; return code == null ? View("Error") : View(model); } // POST: /Account/ResetPassword [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) { if (!ModelState.IsValid) { return View(model); } var user = await UserManager.FindByIdAsync(model.Id); if (user == null) { return RedirectToAction("ResetPasswordConfirmation", "Account"); } var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password); if (result.Succeeded) { return RedirectToAction("ResetPasswordConfirmation", "Account"); } AddErrors(result);

Page 45: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

45

45

return View(); } // GET: /Account/ResetPasswordConfirmation [AllowAnonymous] public ActionResult ResetPasswordConfirmation() { return View(); } ViewModels

public class LoginViewModel { [Required] [Display(Name = "Courrier électronique")] [EmailAddress] public string Email { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Mot de passe")] public string Password { get; set; } [Display(Name = "Mémoriser le mot de passe ?")] public bool RememberMe { get; set; } } public class ForgotPasswordViewModel { [Required] [EmailAddress] [Display(Name = "E-mail")] public string Email { get; set; } } public class ResetPasswordViewModel { [Required] public string Id { get; set; } [Required] [StringLength(100, ErrorMessage = "La chaîne {0} doit comporter au moins {2} caractères.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Mot de passe")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirmer le mot de passe")] [Compare("Password", ErrorMessage = "Le nouveau mot de passe et le mot de passe de confirmation ne correspondent pas.")] public string ConfirmPassword { get; set; } public string Code { get; set; } }

Page 46: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

46

46

Vues:

- Login (pour se connecter) …Vue dans le dossier « Account » des vues « Views »

- Pour la réinitalisalisation de mot de passe : ForgotPassword, ForgotPasswordConfirmation,

ResetPassword, ResetPasswordConfirmation

- Lockout (affichée si l’utilsateur se trompe trop de fois dans ses identifiants), Error (dossier

« Shared »)

Login

@using MvcFromScratch.Models @model LoginViewModel @{ ViewBag.Title = "Connexion"; } <h2>@ViewBag.Title.</h2> @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) { @Html.AntiForgeryToken() <h4>Utilisez un compte local pour vous connecter.</h4> <hr /> @Html.ValidationSummary(true) <div> @Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email) @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) </div> <div> @Html.LabelFor(m => m.Password) @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) </div> <div> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> <div> <input type="submit" value="Connexion" /> </div> <p> @Html.ActionLink("Mot de passe oublié?", "ForgotPassword") </p> <p> @Html.ActionLink("S'inscrire comme nouvel utilisateur", "Register") </p> } <div> @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) </div>

Page 47: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

47

47

ForgotPasword

@model MvcFromScratch.Models.ForgotPasswordViewModel @{ ViewBag.Title = "Vous avez oublié votre mot de passe ?"; } <h2>@ViewBag.Title.</h2> @using (Html.BeginForm("ForgotPassword", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <h4>Entrez une adresse de messagerie.</h4> <hr /> @Html.ValidationSummary() <div> @Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email) </div> <div> <input type="submit" value="Lien de courrier électronique" /> </div> } ForgotPasswordConfirmation

@{ ViewBag.Title = "Confirmation du mot de passe oublié"; } <hgroup class="title"> <h1>@ViewBag.Title.</h1> </hgroup> <div> <p> Vérifiez votre adresse de messagerie pour réinitialiser votre mot de passe. </p> </div>

ResetPasword

@model MvcFromScratch.Models.ResetPasswordViewModel @{ ViewBag.Title = "Réinitialiser le mot de passe"; } <h2>@ViewBag.Title.</h2> @using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <h4>Réinitialisez votre mot de passe.</h4> <hr /> @Html.ValidationSummary() @Html.HiddenFor(model => model.Id) @Html.HiddenFor(model => model.Code) <div> @Html.LabelFor(m => m.Password) @Html.PasswordFor(m => m.Password) </div> <div> @Html.LabelFor(m => m.ConfirmPassword) @Html.PasswordFor(m => m.ConfirmPassword) </div> <div> <input type="submit" value="Réinitialiser" /> </div> }

Page 48: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

48

48

ResetPasswordConfirmation

@{ ViewBag.Title = "Mot de passe réinitalisé"; } <hgroup class="title"> <h1>@ViewBag.Title.</h1> </hgroup> <div> <p> Votre mot de passe a été réinitialisé. Veuillez @Html.ActionLink("cliquer ici pour vous connecter", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" }) </p> </div>

Connexion «externe » avec Facebook, Google, Twitter

Facebook

Développeurs Facebook

1. Créer une nouvelle application : Menu « My Apps » « add a new app » … web

2. Donner un nom à l’application puis « Create App Id »

3. Donner l’url du site « http://localhost:7211/ » par exemple et un email

Cliquer sur show

(demande le mot de

passe facebook) pour

afficher « app secret »

Page 49: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

49

49

4. Passer le statut de l’application en « public » (on peut créer aussi une application de test)

5. Si ce n’est fait installer le package … PM> install-package Microsoft.Owin.Security.Facebook

6. Rendez-vous dans « Startup.Auth.cs » dossier « App_Start », dé-commenter et entrer l’app id

et l’app secret

app.UseFacebookAuthentication( appId: "475813752569575", appSecret: "123456789abcdefg");

L’utilisateur est ajouté dans la table « Asp.NetUsers » sans mot de passe ainsi que dans la table

« AspNetUserLogins » avec son « UserId »

Page 50: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

50

50

Google

Développeurs Google

1. Créer un projet (donner un nom)

2. Créer un identifiant client

Toujours indiquer « signin-google » en url

de redirection

Page 51: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

51

51

3. Activer « Google+ Api »

4. Si ce n’est fait installer le package …

PM> install-package Microsoft.Owin.Security.Google 5. Rendez-vous dans « Startup.Auth.cs » dossier « App_Start » et dé-commenter et entrer le

« Client id » et le « Client secret »

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "903536450598-ps3vsah291ef6iekkqtqflc2d0g746hj.apps.googleusercontent.com", ClientSecret = "123456789abcdefg" });

Page 52: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

52

52

Twitter

Développeurs Twitter

Code supplémentaire // POST: /Account/ExternalLogin [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult ExternalLogin(string provider, string returnUrl) { // Demandez une redirection vers le fournisseur de connexions externe return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); } // GET: /Account/ExternalLoginCallback [AllowAnonymous] public async Task<ActionResult> ExternalLoginCallback(string returnUrl) { var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { return RedirectToAction("Login"); } var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false }); case SignInStatus.Failure: default: // Si l'utilisateur n'a pas de compte ViewBag.ReturnUrl = returnUrl; ViewBag.LoginProvider = loginInfo.Login.LoginProvider; return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email }); } } // POST: /Account/ExternalLoginConfirmation [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "Manage"); } if (ModelState.IsValid) { // Obtenez des informations sur l’utilisateur auprès du fournisseur var info = await AuthenticationManager.GetExternalLoginInfoAsync(); if (info == null)

Page 53: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

53

53

{ return View("ExternalLoginFailure"); } var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await UserManager.CreateAsync(user); if (result.Succeeded) { result = await UserManager.AddLoginAsync(user.Id, info.Login); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); return RedirectToLocal(returnUrl); } } AddErrors(result); } ViewBag.ReturnUrl = returnUrl; return View(model); } internal class ChallengeResult : HttpUnauthorizedResult { private const string XsrfKey = "XsrfId"; public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null) { } public ChallengeResult(string provider, string redirectUri, string userId) { LoginProvider = provider; RedirectUri = redirectUri; UserId = userId; } public string LoginProvider { get; set; } public string RedirectUri { get; set; } public string UserId { get; set; } public override void ExecuteResult(ControllerContext context) { var properties = new AuthenticationProperties { RedirectUri = RedirectUri }; if (UserId != null) { properties.Dictionary[XsrfKey] = UserId; } context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); } }

Page 54: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

54

54

ViewModels

public class ExternalLoginListViewModel { public string ReturnUrl { get; set; } } public class ExternalLoginConfirmationViewModel { [Required] [Display(Name = "Courrier électronique")] public string Email { get; set; } }

Vues

_ExternalLoginsListPartial

@model MvcFromScratch.Models.ExternalLoginListViewModel @using Microsoft.Owin.Security <h4>Utilisez un autre service pour vous connecter.</h4> <hr /> @{ var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes(); if (loginProviders.Count() == 0) { <div> <p> Il n'existe aucun service d'authentification externe configuré. Consultez <a href="http://go.microsoft.com/fwlink/?LinkId=403804">cet article</a> pour des détails sur la configuration de cette application ASP.NET en vue de la prise en charge de la connexion via des services externes. </p> </div> } else { using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = Model.ReturnUrl })) { @Html.AntiForgeryToken() <div id="socialLoginList"> <p> @foreach (AuthenticationDescription p in loginProviders) { <button type="submit" class="btn btn-default" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Connexion avec votre compte @p.Caption">@p.AuthenticationType</button> } </p> </div> } } }

Page 55: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

55

55

ExternalLoginConfirmation

@model MvcFromScratch.Models.ExternalLoginConfirmationViewModel @{ ViewBag.Title = "S’inscrire"; } <h2>@ViewBag.Title.</h2> <h3>Associer votre compte @ViewBag.LoginProvider.</h3> @using (Html.BeginForm("ExternalLoginConfirmation", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <h4>Formulaire d'association</h4> <hr /> @Html.ValidationSummary(true) <p> Vous avez été authentifié avec succès avec <strong>@ViewBag.LoginProvider</strong>. Veuillez entrer ci-dessous un nom d'utilisateur pour ce site et cliquer sur le bouton S'inscrire pour valider la connexion. </p> <div> @Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email) @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) </div> <div> <input type="submit" value="Inscription" /> </div> } ExternalLoginFailure

@{ ViewBag.Title = "Échec de la connexion"; } <hgroup> <h2>@ViewBag.Title.</h2> <h3 class="text-danger">Échec de la connexion auprès du service.</h3> </hgroup>

Exemples : Tutorial, et ici

PM> Install-Package Microsoft.AspNet.Identity.Samples –Pre

c. Autorisations (attribut « Authorize »)

On peut l’appliquer à une action d’un contrôleur

public class PeopleController : Controller { [Authorize] public ActionResult Index() { return View(); } }

Page 56: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

56

56

… ou à tout le contrôleur.

[Authorize] public class PeopleController : Controller { [AllowAnonymous] public ActionResult Index() { return View(); } }

… Autoriser l’accès à un rôle, utilisateur, etc. [Authorize(Roles="admin, member")]

ReturnUrl

Si on essaie d’accéder à une vue nécessitant d’être authentifié on est redirigé vers la page de

login.

Une fois authentifié on est redirigé …

ValidateAntiForgeryToken

Pour contrer les attaques malveillantes

[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(Person person) { if (ModelState.IsValid) { _peopleRepository.Add(person); return RedirectToAction("Index"); } return View(person); }

…Dans la vue

@using (Html.BeginForm()) { @Html.ValidationSummary(true) @Html.AntiForgeryToken()

Permet un accès anonyme à

une action

Page 57: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

57

57

AntiXSS

[HttpPost] public ActionResult Create(Person person) { if (ModelState.IsValid) { person.LastName = Sanitizer.GetSafeHtmlFragment(person.LastName); _peopleRepository.Add(person); return RedirectToAction("Index"); } return View(person); }

d. SSL // GET: /Account/Login [RequireHttps] [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); }

Page 58: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

58

58

e. Projet Visual Studio 2012

InitializeSimpleMembership et WebSecurity

Spécification de la chaine de connexion utilisée(DefaultConnection) WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

La base de données correspondant à la chaine de connexion est créée lors de l’enregistrement du

premier membre si elle n’existe pas.

Il est possible d’ajouter ses champs personnalisés et modifier la table « UserProfile » de la base

avec la commande (console du gestionnaire de packages)

PM> Update-Database -Verbose + enable-migrations

On peut également supprimer « InitializeSimpleMembership » et utiliser sa propre connexion

.Ajouter « WebSecurity.InitializeDatabaseConnection » dans global.asax et remplacer

« UsersContext » par son propre DbContext.

Page 59: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

59

59

[Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } }

// persist cookie = true bool isLogged = WebSecurity.Login("username", "password",true); WebSecurity.CreateUserAndAccount("username", "password");

Le password est haché automatiquement Si l’utilisateur coche « mémoriser le mot de passe » lorsqu’il se entre ses

informations de connexion dans la page de login, un cookie est créé. OAuth et OpenID avec projet Visual Studio 2012

SimpleRoleProvider et SimpleMembershipProvider

Web.config

<system.web> <!-- etc. --> <roleManager enabled="true" defaultProvider="simple"> <providers> <clear/> <add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/> </providers> </roleManager> <membership defaultProvider="simple"> <providers> <clear/> <add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"/> </providers> </membership> </system.web>

var roles = (SimpleRoleProvider)Roles.Provider; var membership = (SimpleMembershipProvider)Membership.Provider; if (!roles.RoleExists("Admin")) roles.CreateRole("Admin"); if (membership.GetUser("Marie", false) == null) membership.CreateUserAndAccount("Marie", "passwword"); if (!roles.GetRolesForUser("Marie").Contains("Admin")) roles.AddUsersToRoles(new[] { "Marie" }, new[] { "Admin" });

Page 60: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

60

60

Register [AllowAnonymous] public ActionResult Register() { return View(); } [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser() { UserName = model.Email, Email = model.Email }; IdentityResult result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } else { AddErrors(result); } } return View(model); }

Login [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.Email, model.Password); if (user != null) { await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("", "Nom d'utilisateur ou mot de passe non valide."); } } return View(model); }

Page 61: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

61

61

7. Localisation

Dates et Monnaies

Dépendent de la culture courante

Exemple : dans la vue on affiche une monnaie et la date, leur formatage change selon la culture.

@{ var money = 9.99m; var today = DateTime.Now.ToShortDateString(); } <div>@money.ToString("c")</div> <div>@today</div>

Web.config

<system.web> <!----> <globalization culture="auto" uiCulture="auto"/> </system.web>

Changer les préférences linguistiques d’IE

… En montant English

…En montant Français

Page 62: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

62

62

Resources

Ajouter un fichier de ressources

Ajouter un fichier de ressources pour la langue par défaut (exemple : Resources.resx) et un

fichier de ressources pour chaque langue supportée par le site (exemple : Resources.en.resx)

Indiquer l’outil personnalisé pour uniquement Resources par défaut.

Exemple en changeant la langue dans les préférences linguistiques d’IE

(LocalizationDemo est le nom du projet)

<div>@LocalizationDemo.Views.Home.Resources.Greeting</div>

On peut également récupérer les ressources dans les contrôleurs var greeting = Resources.Greeting;

Et utiliser les ressources avec les data annotations [Display(ResourceType=typeof(Resources),Name="Greeting")] public string FullName { get; set; }

Page 63: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

63

63

8. Less Installer l’ extension pour Visual Studio « Web Essentials » (aperçu CSS, génération de la feuille

de Styles, minimisation, etc.)

9. Dependency Injection (DI)

Avec Ninject

public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); RegisterServices(); } private void RegisterServices() { var kernel = new StandardKernel(); DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel)); kernel.Bind<IPeopleRepository>().To<FakePeopleRepository>(); } } public class NinjectDependencyResolver :IDependencyResolver { private readonly IKernel _kernel; public NinjectDependencyResolver(IKernel kernel) { this._kernel = kernel; } public object GetService(Type serviceType) { return _kernel.TryGet(serviceType, new IParameter[0]); } public IEnumerable<object> GetServices(Type serviceType) { return _kernel.GetAll(serviceType, new IParameter[0]); } }

Page 64: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

64

64

10. Upgrade Visual Studio 2013 ne prend en charge MVC qu’à partir de la version 4.

Upgrade de MVC2 vers MVC3 avec ASP.NET MVC 3 Application Upgrader

Upgrade de MVC3 vers MVC4

Ouvrir la solution (dont le projet Mvc ne peut être chargé) dans Visual Studio 2013

… chercher « Auto upgrade mvc 3 to mvc4 » avec le gestionnaire de package NuGet

Il se peut qu’il faille ajouter une référence à « Microsoft.AspNet.Web.Optimization » (package NuGet) ensuite.

Cibler le Framework 4.0 peut aussi éviter des problèmes de versions de fichiers.

Page 65: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

65

65

II. Web Api

1. Web Api config

La route par défaut pour un contrôleur Web Api

2. Contrôleur Web Api

a. HTTP Status codes

GET : 200 (ok), 404 (not found), 400, 500

POST : 201 (created), 400 (bad request), 500 (internal server error)

PUT : 200, 404, 400, 500

PATCH : 200,404,400,500

DELETE : 204 (no content), 404, 400, 500

Général : 401 (unauthorized), 403 (forbidden), 405 (method not allowed)

HttpStatusCode

b. Ajout d’un contrôleur Web Api

Menu contextuel sur le dossier « Controllers » du projet

Page 66: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

66

66

c. Contrôleur Web API avec IhttpActionResult

Permet de simplifier l’écriture (et réduire le code) de réponses HTTP en utilisant des méthodes :

Classe implémentant de IhttpResult Méthode OkResult Ok NotFoundResult NotFound ExceptionResult UnauthorizedResult Unauthorized BadRequestResult BadRequest ConflictResult Conflict RedirectResult Redirect InvalidModelStateResult

public class PeopleController : ApiController { private IPeopleRepository peopleRepository; public PeopleController() : this(new FakePeopleRepository()) { } public PeopleController(IPeopleRepository peopleRepository) { this.peopleRepository = peopleRepository; } [HttpGet] public IHttpActionResult Get() { try { var people = peopleRepository.GetAll(); return Ok(people); } catch (Exception ex) { return InternalServerError(ex); } } [HttpGet] public IHttpActionResult Get(int id) { try { var person = peopleRepository.GetOne(id); if (person != null) { return Ok(person); } else { return NotFound(); } } catch (Exception ex) { return InternalServerError(ex); } } [HttpPost] public IHttpActionResult Post([FromBody]Person person) {

Injection de

dépendances

Page 67: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

67

67

try { var result = peopleRepository.Add(person); return Created(Request.RequestUri + "/" + result.Id.ToString(), result); } catch (Exception ex) { return InternalServerError(ex); } } [HttpPut] public IHttpActionResult Put(int id, [FromBody]Person person) { try { if (person == null) return BadRequest(); var personToUpdate = peopleRepository.GetOne(id); if (personToUpdate == null) { return NotFound(); } var result = peopleRepository.Update(person); return Ok(result); } catch (Exception ex) { return InternalServerError(ex); } } [HttpDelete] public IHttpActionResult Delete(int id) { try { var personToDelete = peopleRepository.GetOne(id); if (personToDelete == null) { return NotFound(); } peopleRepository.Delete(id); return StatusCode(HttpStatusCode.NoContent); } catch (Exception ex) { return InternalServerError(ex); } } }

Page 68: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

68

68

d. Contrôleur Web API avec HttpResponseMessage public class PeopleController : ApiController { private IPeopleRepository peopleRepository; public PeopleController() : this(new FakePeopleRepository()) { } public PeopleController(IPeopleRepository peopleRepository) { this.peopleRepository = peopleRepository; } [HttpGet] public HttpResponseMessage Get() { try { var people = peopleRepository.GetAll(); return Request.CreateResponse(HttpStatusCode.OK,people); } catch (Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError,ex); } } [HttpGet] public HttpResponseMessage GetOne(int id) { try { var person = peopleRepository.GetOne(id); if (person != null) { return Request.CreateResponse(HttpStatusCode.OK,person); } else { return Request.CreateResponse(HttpStatusCode.NotFound); } } catch (Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); } } [HttpPost] public HttpResponseMessage Post([FromBody]Person person) { try { var result = peopleRepository.Add(person); return Request.CreateResponse(HttpStatusCode.Created, result); } catch (Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); } } [HttpPut] public HttpResponseMessage Put(int id,[FromBody]Person person) { try

On pourrait également retourner

une liste générique en résultat par

exemple

On pourrait également retourner

une instance de classe (exemple

« Person »)

Page 69: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

69

69

{ if (person == null) return Request.CreateResponse(HttpStatusCode.BadRequest); var personToUpdate = peopleRepository.GetOne(id); if (personToUpdate == null) { return Request.CreateResponse(HttpStatusCode.NotFound); } var result = peopleRepository.Update(person); return Request.CreateResponse(HttpStatusCode.OK, result); } catch (Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); } } [HttpDelete] public HttpResponseMessage Delete(int id) { try { var personToDelete = peopleRepository.GetOne(id); if (personToDelete == null) { return Request.CreateResponse(HttpStatusCode.NotFound); } peopleRepository.Delete(id); return Request.CreateResponse(HttpStatusCode.NoContent); } catch (Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); } } }

Retour au format Json par défaut. Si on désire un retour au format Xml…DataMember(membres

à intégrer dans la réponse) et DataContract (System.Runtime.Serialization) [Serializable] [DataContract] public class Person { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public string Twitter { get; set; } } …Et dans le header accept :text/xml

Page 70: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

70

70

Test du Service avec Fiddler

GET

POST

Retour au format JSON de l’élément créé

PUT

DELETE

Ajout du type de contenu

Ajout du paramètre « id » à

l’url et passage de l’élément

modifié

« get one »

Page 71: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

71

71

3. Attribut “Route”

Permet de personnaliser ses routes et d’éviter les conflits entre routes.

[HttpGet] [Route("api/people/{id}/twitter")] public HttpResponseMessage GetTwitter(int id) { // etc. }

Route Description [Route("api/people/{id}/twitter")] Route personnalisée [Route("api/people/{id:int:min(1)}/twitter")] Contraintes [Route("api/people/{id:int}")] [Route("api/people/{name:alpha}")]

Multiples routes

[Route("api/people/{id?}")] Appliquer à tout le contrôleur [RoutePrefix("api/people")] Prefix pour toutes les routes du contrôleur [RouteArea("admin")] Mvc Areas

4. Injection de dépendances

Avec Ninject

Ajout du package NuGet « NInject »

… ainsi que (pour Web Api)

Global.asax

public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); RegisterServices(); } private void RegisterServices() { var kernel = new StandardKernel(); GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel); kernel.Bind<IPeopleRepository>().To<PeopleRepository>(); } }

Page 72: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

72

72

Le contrôleur n’a plus besoin de constructeur par défaut

5. Projet Client

a. dataService JavaScript

(Pour projet SPA, Angular, Durandal,…). Avec Knockout par exemple : var dataService = function () { 'use strict' var urlBase = 'http://localhost:12107/api/People', getPeople = function () { return $.getJSON(urlBase); }, searchPeople = function (search) { return $.getJSON(urlBase + '/find/' + search); }, getPerson = function (id) { return $.getJSON(urlBase + '/' + id); }, addPerson = function (person) { return $.ajax({ url: urlBase, type: 'POST', dataType: 'json', contentType: 'application/json; charset=utf-8', data: ko.toJSON(person) }); }, updatePerson = function (person) { return $.ajax({ url: urlBase, type: 'PUT', dataType: 'json', contentType: 'application/json; charset=utf-8', data: ko.toJSON(person) }); }, deletePerson = function (id) { return $.ajax({ url: urlBase + '/' + id, type: 'DELETE' }); }; return { getPeople: getPeople, searchPeople: searchPeople, getPerson: getPerson, updatePerson: updatePerson, addPerson: addPerson, deletePerson: deletePerson }; }();

Page 73: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

73

73

b. HttpClient

(projets WinRT, Wpf,etc.)

public class PeopleService { string urlBase ="http://localhost:12107/api/People"; public async Task<Person[]> GetAll() { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync(urlBase); string resultContent = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Person[]>(resultContent); } } public async Task<Person> GetOne(int personID) { using (HttpClient client = new HttpClient()) { HttpResponseMessage result = await client.GetAsync(string.Format("{0}/{1}", urlBase, personID)); string resultContent = await result.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Person>(resultContent); } } public async void Add(Person person) { using (HttpClient client = new HttpClient()) { string json = JsonConvert.SerializeObject(person); HttpResponseMessage response = await client.PostAsync(urlBase, new StringContent(json, Encoding.UTF8, "application/json")); string resultContent = await response.Content.ReadAsStringAsync(); person = JsonConvert.DeserializeObject<Person>(resultContent); } } public async void Update(Person person) { using (HttpClient client = new HttpClient()) { string json = JsonConvert.SerializeObject(person); HttpResponseMessage response = await client.PutAsync(urlBase, new StringContent(json, Encoding.UTF8, "application/json")); string resultContent = await response.Content.ReadAsStringAsync(); person = JsonConvert.DeserializeObject<Person>(resultContent); } } public async void Delete(int personID) { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.DeleteAsync(string.Format("{0}/{1}", urlBase, personID)); response.EnsureSuccessStatusCode(); } } }

Page 74: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

74

74

Il existe également des librairies facilitant encore l’utilisation de HtppClient comme EasyHttp

public class EasyHttpPeopleService { string urlBase = "http://localhost:12107/api/People"; public Person[] GetAll() { HttpClient client = new HttpClient(); HttpResponse response = client.Get(urlBase); Person[] result = response.StaticBody<Person[]>(); return result; } public Person GetOne(int personID) { HttpClient client = new HttpClient(); HttpResponse response = client.Get(string.Format("{0}/{1}", urlBase, personID)); Person result = response.StaticBody<Person>(); return result; } public void Add(Person person) { HttpClient client = new HttpClient(); client.Post(urlBase, person, "application/json"); } public void Update(Person person) { HttpClient client = new HttpClient(); client.Put(urlBase, person, "application/json"); } public void Delete(int personID) { HttpClient client = new HttpClient(); client.Delete(string.Format("{0}/{1}", urlBase, personID)); } }

Page 75: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

75

75

6. Cors

Installer avec les packages NuGet

PM> Install-Package Microsoft.AspNet.WebApi.Cors

… Dans WebApiConfig

… Sur le contrôleur Web API

[EnableCorsAttribute("http://localhost:63679", "*","*")] public class PeopleController : ApiController { public IHttpActionResult Get() { var file = HostingEnvironment.MapPath(@"~/App_Data/people.json"); var json = File.ReadAllText(file); var people = JsonConvert.DeserializeObject<List<Person>>(json); return Ok(people); } }

Les ports ne correspondant pas,

on a une erreur

Ajouter l’attribut « EnableCorsAttribute ». Le premier

argument correspondant à l’URL du client (on

pourrait également mettre « * »), le second aux

headers puis les méthodes.

Page 76: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

76

76

7. Formatters pour le « Mapping »

Dans le Fichier Json les noms des propriétés sont en camelCase, alors que les propriétés des modèles

eux sont en PascalCase.

public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Configuration et services de l'API Web // Configurer l'API Web pour utiliser uniquement l'authentification de jeton du porteur. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Itinéraires de l'API Web config.MapHttpAttributeRoutes(); config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.EnableCors(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }

8. OData

Installer avec les packages NuGet

PM> Install-Package Microsoft.AspNet.WebApi.OData

Puis pour les méthodes des contrôleurs

[EnableQuery()] [ResponseType(typeof(Person))] public IHttpActionResult Get() { try { var result = peopleRepository.GetAll(); return Ok(result.AsQueryable()); } catch (Exception ex) { return InternalServerError(ex); } }

Site, Documentation

Résultat retourné AsQueryable.

Ajouter l’attribut

« EnableQuery »

Si on n’utilise pas

« IHttpActionResult » retourner

« IQueryable<Person> » dans

l’exemple

Page 77: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

77

77

9. Authentification Web Api

Server

« PeopleController » réclame d’être authentifié .

[Authorize] public class PeopleController : ApiController { private static List<Person> people = new List<Person>() { new Person(1,"John","Papa","@john_papa"), new Person(2, "Ryan", "Niemeyer", "@rpniemeyer"), new Person(3, "Steve", "Sanderson", "@stevensanderson"), new Person(4, "Ward", "Bell", "@wardbell"), new Person(5, "Scott", "Allen","@OdeToCode"), new Person(6,"Yacine","Khammal","@YacineKhammal") }; [HttpGet] public IEnumerable<Person> Get() { return people; } } Startup.Auth et AccountController différent de la version

« Mvc ».L’ApplicationUserManager(IdentityConfig.cs) change peu.

AccountController Startup.Auth.cs

Page 78: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

78

78

Client : On n’est autorisé à afficher la liste des personnes qu’une fois authentifié. <body> <header> <!--connexion --> <div id="login"> <form id="loginForm"> <input type="text" name="userName" placeholder="Nom d'utilisateur" value="[email protected]" /> <input type="password" name="password" placeholder="Mot de passe" value="Abc123_" /> <input type="submit" id="loginInput" value="Valider" /> <input type="button" id="showRegisterForm" value="Créer un compte?" /> </form> </div> <!-- enregistrement --> <div id="register"> <form id="registerForm"> <input type="text" id="userName" name="userName" value="[email protected]" /> <input type="text" name="email" value="[email protected]" /> <input type="password" id="password" name="password" value="Abc123_" /> <input type="password" name="confirmPassword" value="Abc123_" /> <input type="submit" id="registerInput" value="Valider" /> <input type="button" id="showLoginForm" value="Connexion" /> </form> </div> <!--connecté --> <div id="loggedIn"></div> </header> <section> <button id="getPeopleListButton">Lister les personnes</button> <div id="container"></div> </section> <script src="Scripts/jquery-2.1.3.js"></script> <script> $(function () { // Show / hide $("#register").hide(); $("#getPeopleListButton").hide(); $("#loggedIn").hide(); $("#showLoginForm").on("click", function () { $("#register").hide(); }); $("#showRegisterForm").on("click", function () { $("#register").show(); }); var accessToken = ""; var loggedIn = false; var register = function () { var url = "api/account/register"; var data = $("#registerForm").serialize(); // récupère les infos saisies dans le formulaire $.post(url, data) .done(function () { alert("Bienvenue !"); login(); // connexion

Page 79: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

79

79

}) .fail(function () { alert("Echec lors de la création du compte."); }); return false; } // login var login = function () { var url = "Token"; var data = $("#loginForm").serialize(); //userName=abc%40laposte.net&email=abc%40laposte.net&password=Abc123_&confirmPassword=Abc123_ data = data + "&grant_type=password"; $.post(url, data) .success(function (data) { accessToken = data.access_token; loggedIn = true; $("#login").hide(); $("#register").hide(); var welcomeMessage = "<h2>Bonjour " + data.userName + "!</h2>"; $("#loggedIn").html(welcomeMessage); $("#loggedIn").show(); $("#getPeopleListButton").show(); }) .fail(function () { alert("Impossible de se connecter. vérifiez vos identifiants."); }); return false; } var getAll = function () { var url = "api/people"; if (loggedIn) { $.ajax(url, { type: "GET", headers: { "Authorization": "Bearer " + accessToken, "Content-Type": "application/x-www-form-urlencoded" } }).success(function (data) { var tableHTML = "<table><tr><th>Nom</th><th>Twitter</th></tr>"; data.forEach(function (person) { tableHTML += "<tr><td>" + person.Name + "</td><td>" + person.Twitter + "</td></tr>"; }); tableHTML += "</table>"; $("#container").html(tableHTML); }) .fail(function (error) { alert(JSON.stringify(error, null, 4)); }); }

Page 80: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

80

80

else { alert("Veuillez vous authentifier svp."); } } $("#loginInput").on("click", login); $("#registerInput").on("click", register); $("#getPeopleListButton").on("click", getAll); }); </script> </body> Login…on récupère le token …

Récupération de la liste de personnes …

Page 81: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

81

81

Activer SSL

Depuis les propriétés du projet

… Puis dans l’onglet Web changer l’URL

URL SSL

Page 82: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

82

82

10. MongoDB

Connexion à une base de données NoSQL MongoDB avec un service WEB MVC.

Drivers :

- MongoDB C# Driver

- Simple-mongodb

- FluentMongo

a. Installation de MongoDB C# driver

Documentation

Deux références sont ajoutées :

Serveur

peopledb

people

MongoClient

MongoServer

MongoDatabase

MongoCollection

Page 83: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

83

83

b. Service WEB

Création d’une classe permettant de se connecter à la base de données.

using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; using MongoDBWithMVC.Properties; namespace MongoDBWithMVC.Models { public class MongoDBContext { public MongoDatabase database; public MongoDBContext() { //mongodb://localhost:27017/ var client = new MongoClient(Settings.Default.MongoDBConnectionString); var server = client.GetServer(); database = server.GetDatabase(Settings.Default.DatabaseName); //peopledb } public MongoCollection<Person> People { get { return database.GetCollection<Person>("people"); } } } }

Le modèle utilisé pour la définition des documents

public class Person { [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; } [BsonElementAttribute("name")] public string Name { get; set; } [BsonElementAttribute("twitter")] public string Twitter { get; set; } }

Pour l’identifiant (_id) attribué

à l’insertion d’un document

Pour la sérialisation lorsque le

nom des éléments est différent

Accès à la collection « people » de la

base

Page 84: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

84

84

Service WEB API

public class PeopleController : ApiController { MongoDBContext context; public PeopleController() { context = new MongoDBContext(); } public IHttpActionResult Get() { try { var result = context.People.FindAll(); return Ok(result); } catch (Exception ex) { return InternalServerError(ex); } } public IHttpActionResult Get(string id) { try { var person = context.People.FindOneById(new ObjectId(id)); if (person != null) { return Ok(person); } else { return NotFound(); } } catch (Exception ex) { return InternalServerError(ex); } } [HttpPost] public IHttpActionResult Post([FromBody]Person person) { try { var result = context.People.Insert(person); return Created(Request.RequestUri + "/" + person.Id.ToString(), person); } catch (Exception ex) { return InternalServerError(ex); } } [HttpPut] public IHttpActionResult Put(string id, [FromBody]Person person) { try {

On utilise la classe de contexte créée

pour se connecter et accéder à la

collection « people »

Méthode « FindAll » pour obtenir

tous les documents

Obtention du document par l’id

Ajout d’un document à la collection

« people »

Page 85: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

85

85

var personToUpdate = context.People.FindOneById(new ObjectId(id)); if (personToUpdate == null) { return NotFound(); } personToUpdate.Name = person.Name; personToUpdate.Twitter = person.Twitter; context.People.Save(personToUpdate); return Ok(personToUpdate); } catch (Exception ex) { return InternalServerError(ex); } } [HttpDelete] public IHttpActionResult Delete(string id) { try { var personToDelete = context.People.FindOneById(new ObjectId(id)); if (personToDelete == null) { return NotFound(); } context.People.Remove(Query.EQ("_id", new ObjectId(id))); return StatusCode(HttpStatusCode.NoContent); } catch (Exception ex) { return InternalServerError(ex); } } }

Modification puis sauvegarde du

document.

On pourrait aussi utiliser la méthode

update+ updatebuilder

Suppression du document par

l’id

Page 86: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

86

86

III. Bootstrap

1. Installation et thèmes On peut « customiser » en sélectionnant seulement les éléments à inclure

Ajout au projet : Télécharger depuis le site ou avec packages NuGet (ou sur Github pour avoir les

fichiers LESS)

Thèmes pour bootstrap

Thème à télécharger sur boostwatch. On renomme le thème par exemple « flatly-bootstrap.css »

que l’on ajoute au projet et on remplace le thème par défaut par celui-ci

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, inital-scale=1" /> <title>Bootstrap demo</title> <link href="css/bootstrap.css" rel="stylesheet" /> <link href="css/bootstrap-theme.css" rel="stylesheet" /> <!--<link href="css/themes/flatly-bootstrap.css" rel="stylesheet" />--> <link href="css/default.css" rel="stylesheet" /> </head> <body> <script src="js/jquery-2.1.3.js"></script> <script src="js/bootstrap.js"></script> </body> </html>

Thème « par défaut » et thème

téléchargé sur boostwatch

Page 87: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

87

87

2. Grid system Grid system sur 12 colonnes : exemple de col-md-1 à col-md-12 occupant toute la largeur.

Taille Classe >=1200px col-lg-xx de 992 à 1200px col-md-xx De 768 à 991px col-sm-xx <768px col-xs-xx

<div class="row"> <div id="main" class="col-md-8 col-sm-10 col-xs-6"><p>Lorem ipsum ... </p></div> <div id="sidebar" class="col-md-4 col-sm-2 col-xs-6">Lorem ... </div> </div>

a. Cacher une colonne selon une résolution

<div id="sidebar" class="col-md-4 hidden-xs">Lorem ipsum ... </div>

col-md-8 et col-md-4 pour la

« sidebar » sur taille « middle »

Cachera la colonne sur mobile

La taille des colonnes s’adapte selon les résolutions

Sur mobile 2 colonnes égales (col-xs-

6)

Page 88: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

88

88

b. Décalage de colonnes avec « offset »

De col-xx-offset-1 à col-xx-offset-12

Ex

<div class="row"> <div class="col-md-8 col-md-offset-4">Lorem ipsum …</div> </div>

c. Image flottante

Thumbnails

<div class="row"> <div class="col-md-12"> <p><img src="images/foodies.jpg" width="300" class="pull-left thumbnail"/>Lorem …</p> </div> </div>

3. Bases

a. Typographie

Documentation

Classes commençant par « text-xx »

<p class="text-muted">Lorem ipsum dolor sit amet</p>

Colonne « col-md-8 » avec

décalage de 4 colonnes « col-md-

offset-4 »

« pull-left » place l’image à gauche (« pull-right »

dispo)

« thumbnail » ajoute une bordure et effet à la

photo

Page 89: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

89

89

b. Boutons, groupes de boutons et dropdowns

Buttons

<button class="btn btn-danger">En savoir plus ...</button>

Dropdowns

<div class="form-group"> <div class="btn-group"> <button class="btn btn-default active">Un</button> <button class="btn btn-default">Deux</button> <div class="btn-group"> <button id="option" class="btn btn-default">Choisir ...</button> <button class="btn btn-default" data-toggle="dropdown"><span class="caret"></span></button> <ul id="options" class="dropdown-menu"> <li><a href="#">Option un</a></li> <li><a href="#">Option deux</a></li> <li class="divider"></li> <li class="disabled"><a href="#">Option trois</a></li> </ul> </div> </div> </div> Script pour changer le texte du bouton <script> $(document).ready(function () { $("#options li a").on("click", function () { var option = $(this).text(); $("#option").text(option); }) }); </script>

On pourrait utiliser des

boutons radio avec label

Page 90: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

90

90

c. Icones

Glyphicons

<button class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="glyphicon glyphicon-chevron-down"></span></button>

d. Formulaires, listes, et tables

Forms, nav, tables

« input-group »

Documentation

<div class="form-group"> <div class="col-md-10"> <div class="input-group"> <span class="input-group-addon">@</span> <input type="email" class="form-control" placeholder="Email"/> </div> </div> </div>

e. Navbar desktop et mobile

Documentation

<header class="container"> <div id="menu" class="nav navbar-default"> <div class="navbar-header"> <button class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="glyphicon glyphicon-chevron-down"></span></button> <h4><a href="#">Boostrap demo</a></h4> </div> <nav class="navbar navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li class="nav active"><a href="#">Accueil</a></li> <li class="nav"><a href="#">A propos</a></li> <li class="nav"><a href="#">Contact</a></li> </ul> </nav> </div> </header>

Version desktop

Page 91: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

91

91

Avec thème « flatly »

Version mobile

Avec thème « flatly »

f. Header et breadcrumb

Header, breadcrumb

<div id="body" class="container"> <ol class="breadcrumb"> <li><a href="index.html">Accueil</a></li> <li class="active">A propos</li> </ol> <div class="page-header"> <h1>Bootstrap demo</h1> <p>Une démonstration du Framework</p> </div>

g. Pagination

Documentation

« breadcrumb »

« header » mis en

forme

Page 92: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

92

92

<ul class="pagination"> <li class="disabled"><a href="#">&laquo;</a></li> <li class="active"><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">&raquo;</a></li> </ul>

h. Well

<p class="well"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lacinia metus quis vulputate semper. </p>

i. Panels

Documentation

Plugins

a. Collapse et accordéon

Documentation

On pourrait ajouter la classe « lead » pour mettre plus en avant

Page 93: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

93

93

b. Boite de dialogue

Documentation

<a href="#mydialogbox" class="btn btn-danger" data-toggle="modal">Ouvrir la boite de dialogue ...</a> <div id="mydialogbox" class="modal fade"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <a href="#" class="close" data-dissmiss="modal">&times;</a> <h3>Une boite de dialogue</h3> </div> <div class="modal-body"> Le contenu de la boite! </div> <div class="modal-footer"> le pied </div> </div> </div> </div>

Depuis jQuery

$("#mydialogbox").modal("show");

c. Alert

Documentation

On place une alerte au-dessus d’un formulaire

« collapse » par défaut que l’on affiche si le

formulaire comporte des erreurs par exemple

Page 94: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

94

94

<div class="alert alert-warning collapse" id="formmessage"> <a href="#" class="close" data-dissmiss="alert">&times;</a> <p>Vous devez remplir tous les champs!</p> </div> <form> <!-- ... -->

$("form").on("submit", function (e) { if($("#email").text()=="") { e.preventDefault(); $("#formmessage").show(); } })

d. Tab

Documentation

<ul class="nav nav-tabs nav-justified"> <li class="active"><a href="#formtab" data-toggle="tab">Contact</a></li> <li><a href="#maptab" data-toggle="tab">Map</a></li> </ul> <div class="tab-content"> <div class="well tab-pane active" id="formtab"> <form> <!-- ... --> </form> </div> <div class="well tab-pane" id="maptab"> <!-- ... --> </div> </div>

e. Tooltip

Documentation

Page 95: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

95

95

Exemple toolptip sur les images (affiche la propriété title)

$("img").tooltip();

On pourrait définir du « html » dans l’attribut « title »

<img id="foodies" src="images/foodies.jpg" width="300" class="pull-left thumbnail" data-html="true" title="<h3>Un petit café?</h3><img src='images/foodies.jpg' class='img-responsive'/>" />

f. Caroussel

Documentation

« data-html »

Page 96: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

96

96

<div class="container"> <div class="row visible-lg visible-md"> <div class="col-lg-8 col-lg-offset-2 col-md-8 col-md-offset-2"> <div id="carousel" class="carousel slide" data-ride="carousel" data-interval="2000"> <!-- indicateurs --> <ol class="carousel-indicators"> <li data-target="#carousel" data-slide-to="0" class="active"></li> <li data-target="#carousel" data-slide-to="1"></li> <li data-target="#carousel" data-slide-to="2"></li> </ol> <!-- slides --> <div class="carousel-inner"> <div class="item active"> <img src="images/image_1.jpg" class="img-responsive" alt="" /> <div class="carousel-caption"><h4>Un petit café?</h4></div> </div> <div class="item"> <img src="images/image_2.jpg" class="img-responsive" alt="" /> <div class="carousel-caption"><h4>Un poussin</h4></div> </div> <div class="item"> <img src="images/image_3.jpg" class="img-responsive" alt="" /> <div class="carousel-caption"><h4>La grande roue</h4></div> </div> </div> <!-- Controls --> <a class="left carousel-control" href="#carousel" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> </a> <a class="right carousel-control" href="#carousel" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> </a> </div> </div> </div> </div>

jQuery

Permet de lancer auto.

(data-interval : intervalle

entre chaque slide en ms)

Contrôles

Indicateurs

Caption

Page 97: ASP.NET MVC et WEB API - romagny13.comromagny13.com/wp-content/uploads/2015/04/Présentation-de-Asp.Net... · 4 4 I. MVC 1. « From scratch » - Démarrer avec un projet Asp.Net vide

97

97

$("#carousel").carousel();