Il s'agit d'une application MVC développée avec .NET Framework 4.8 à des fins d'apprentissage.
Résultats de l'action
| Taper | Méthode d'aide |
|---|---|
| Voir Result | Voir() |
| PartialViewResult | PartialView () |
| Contenu | Contenu() |
| Rediffusion | Réorienter() |
| Rediriger | Redirectoaction () |
| Jsonrsult | JSON () |
| Filersult | Déposer() |
| HttpnotfoundResult | Httpnotfound () |
| Résulter de vide | - |
Quelques exemples
public ActionResult Test ( )
{
return View ( data ) ;
return Content ( "Hello World!" ) ;
return HttpNotFound ( ) ;
return new EmptyResult ( ) ;
return RedirectToAction ( "Index" , "Home" , new { page = "1" , sortBy = "name" } ) ;
} Routage basé sur la convention: dans RouteConfig.cs
routes . MapRoute (
"MoviesByReleaseDate" , //name of route
"movies/released/{year}/{month}" , //route url
new { controller = "Movies" , action = "ByReleaseDate" } , //default corresponding controller and actions
new { year = @"2020|2021" , month = @"d{2}" } ) ; //constraints for parameters Routing d'attribut : dans RouteConfig.cs Ajouter routes.MapMvcAttributeRoutes(); Avant le contrôleur, utilisez l'attribut [Route("url template")] . Des contraintes comme Min, Max, MinLength, MaxLength, INT, Float, GUID peuvent être utilisées.
[ Route ( "movies/released/{year:regex( \ d{4}:range(1800,2021))}/{month:regex( \ d{2}:range(1,12))}" ) ]
public ActionResult ByReleaseDate ( int year , int month )
{
return Content ( year + "/" + month ) ;
} public ActionResult Test ( )
{
var movie = new Movie ( ) { Name = "Shrek!" } ;
ViewData [ "Movie" ] = movie ;
ViewBag . Movie = movie ;
return View ( movie ) ;
} < h2 > @Model.Name </ h2 > <!-- preffered way -->
< h2 > @( ((Movie) ViewData["Movie"]).Name) </ h2 > <!-- ugly way / dont use -->
< h2 > @ViewBag.Movie.Name </ h2 > <!-- casted at runtime / not safe --> public class RandomMovieViewModel
{
public Movie Movie { get ; set ; }
public List < Customer > Customers { get ; set ; }
} public class MoviesController : Controller
{
// GET: Movies
public ActionResult Random ( )
{
//adding data
var movie = new Movie ( ) { Name = "Shrek!" } ;
var customers = new List < Customer >
{
new Customer { Name = "cust1" } ,
new Customer { Name = "cust2" }
} ;
//filing viewmodel with data
var viewModel = new RandomMovieViewModel ( )
{
Movie = movie ,
Customers = customers
} ;
return View ( viewModel ) ;
}@ *
this is a razor comment
* @
@ {
//multiple lines
//when razor sees html prints it and when razor sees csharp interprets it
}
@ {
var className = Model . Customers . Count > 0 ? "popular" : null ;
}
< h2 class = "@className" > @Model . Movie . Name < / h2 > < ! -- preferred way -- >
@if ( Model . Customers . Count == 0 )
{
< p > No one has rented this movie before . < / p >
}
< ul >
@foreach ( var customer in Model . Customers )
{
< li > @customer . Name < / li >
}
< / ul > Créez une vue dans les vues en tant que vue et sélectionnez Affichage partiel. Utilisation dans une autre vue @Html.Partial("_PartialView", Model.Data)




Framework Entity: un ORM qui mappe les données dans une base de données relationnelle à nos objets en utilisant un fichier contextuel.
Linq: méthode comme les requêtes SQL.
Workflows: base de données d'abord, code d'abord.
DB First: Concevoir les tables de la base de données d'abord, laissez plus ultiage EF générer des classes de domaine en fonction des tableaux.
Code d'abord: Créez d'abord les classes de domaine, laissez-nous plus tard générer des tables de base de données pour nous.
DBSet au nom de la table dans le contexte: classe DBContext dans Package Manager Console PM > enable-migrations , PM> add-migration migrationName , PM> update-database
Endring DB: Mettez les commandes SQL dans une méthode Migrations Up ()
dans le contrôleur
private Context _context ;
public CustomersController ( )
{
_context = new Context ( ) ;
}
//...
public ActionResult Index ( )
{
var customers = _context . Customers . ToList ( ) ;
return View ( customers ) ;
}
//...
public ActionResult Details ( int id )
{
var customer = _context . Customers . Single ( c => c . Id == id ) ;
return View ( customer ) ;
} Chargez une table étrangère relationnelle : _context.Customer.Include(c=>c.MembershipType).ToList();





En vue:
@using ( Html . BeginForm ( actionName : "Create" , controllerName : "Customers" ) )
{
< div class = "form-group" >
@Html . LabelFor ( m => m . Name )
@Html . TextBoxFor ( m => m . Name , new { @class = "form-control" } )
< / div >
} Dans le modèle avec annotation de données:
[ Display ( Name = "Date of Birth" ) ]
public DateTime ? Birthdate { get ; set ; } ou en vue avec <label for="Birthdate">Date of Birth</label>
Créer ViewModel:
public class NewCustomerViewModel
{
public IEnumerable < MembershipType > MembershipTypes { get ; set ; }
public Customer Customer { get ; set ; }
}Dans Controller:
var membershipTypes = _context . MembershipTypes . ToList ( ) ;
var viewModel = new NewCustomerViewModel ( )
{
MembershipTypes = membershipTypes
} ;En vue:
< div class =" form-group " >
@Html.LabelFor(m = > m.Customer.MembershipTypeId)
@Html.DropDownListFor(m = > m.Customer.MembershipTypeId, new SelectList(Model.MembershipTypes,"Id","Name"),"Select Membership Type", new { @class = "form-control" })
</ div > Dans Controller:
[ HttpPost ]
public ActionResult Create ( Customer customer )
{
//...
return View ( ) ;
}Affichage à assurer le nom d'action et le nom du contrôleur
( Html . BeginForm ( actionName : "Create" , controllerName : "Customers" ) )
//... [ HttpPost ]
public ActionResult Create ( Customer customer )
{
_context . Customers . Add ( customer ) ;
_context . SaveChanges ( ) ;
return RedirectToAction ( "Index" , "Customers" ) ;
} Remplissez les données avec un élément correspondant à partir de l'ID dans le contrôleur:
public ActionResult Edit ( int id )
{
var customer = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customer == null )
return HttpNotFound ( ) ;
var viewModel = new CustomerFormViewModel ( )
{
Customer = customer ,
MembershipTypes = _context . MembershipTypes . ToList ( )
} ;
return View ( "CustomerForm" , viewModel ) ;
}
} S'il n'existe pas, ajoutez, s'il existe une mise à jour. Dans le contrôleur map les attributs
public ActionResult Save ( Customer customer )
{
if ( customer . Id == 0 )
_context . Customers . Add ( customer ) ;
else
{
var customerInDb = _context . Customers . Single ( c => c . Id == customer . Id ) ;
customerInDb . Name = customer . Name ;
customerInDb . Birthdate = customer . Birthdate ;
customerInDb . MembershipTypeId = customer . MembershipTypeId ;
customerInDb . IsSubscribedToNewsletter = customer . IsSubscribedToNewsletter ;
}
_context . SaveChanges ( ) ;
return RedirectToAction ( "Index" , "Customers" ) ;
}Ajoutez le champ d'ID dépendant en vue comme caché:
@Html.HiddenFor(m= > m.Customer.Id)


Étape 1: Ajouter des annotations dans le modèle, étape2: ajouter le contrôle de validation dans le contrôleur. Lorsqu'il n'est pas un formulaire de retour avec les données des utilisateurs
if ( ! ModelState . IsValid )
{
var viewModel = new CustomerFormViewModel
{
Customer = customer ,
MembershipTypes = _context . MembershipTypes . ToList ( )
} ;
return View ( "CustomerForm" , viewModel ) ;
}Étape3: Ajoutez un message de validation à Afficher:
@Html.ValidationMessageFor(m= > m.Customer.Name)Erreur de validation de style accédez à ces classes et stylisez:
. field-validation-error {
color : red;
}
. input-validation-error {
border : 2 px red;
}Message de validation primordial dans le modèle Ajouter ceci à l'annotation de données requise
[ Required ( ErrorMessage = "Please enter customer's name." ) ]
[ StringLength ( 255 ) ]
public string Name { get ; set ; } Étape 1: Créez une classe qui hérite de validationAttribute (en utilisant System.ComponentModel.DataAnnotations)
public class Min18YearsIfAMember : ValidationAttribute
{
protected override ValidationResult IsValid ( object value , ValidationContext validationContext )
{
var customer = ( Customer ) validationContext . ObjectInstance ;
if ( customer . MembershipTypeId == 0 || customer . MembershipTypeId == 1 )
{
return ValidationResult . Success ;
}
if ( customer . Birthdate == null )
{
return new ValidationResult ( "Birthdate is required." ) ;
}
var age = DateTime . Today . Year - customer . Birthdate . Value . Year ;
return ( age >= 18 )
? ValidationResult . Success
: new ValidationResult ( "Customer should be at least 18 years old to go on a membership." )
}
}Étape2: ajouter l'annotation de données au modèle
[ Display ( Name = "Membership Type" ) ]
[ Min18YearsIfAMember ]
public byte MembershipTypeId { get ; set ; }Étape 3: Ajouter un message à la vue
@Html.ValidationMessageFor(m= > m.Customer.MembershipTypeId)@Html.ValidationSummary(true, "Please fix the following errors.")ExcludePropertyErrors: True cache le message de liste des erreurs individuelles: le message affiché à l'utilisateur (pourrait être stylisé)
Ajoutez ceci aux formulaires en vue
@section scripts {
@Scripts . Render ( "~/bundles/jqueryval" )
} Dans les vues, utilisez cette aide HTML:
@Html . AntiForgeryToken ( )et dans l'action du contrôleur, ajoutez cette annotation de données:
Dans les contrôleurs, créer une API Web et ajouter ceci à global.asax.js:
GlobalConfiguration . Configure ( WebApiConfig . Register ) ;Dans le contrôleur, initialisez le contexte:
private Context _context ;
public CustomersController ( )
{
_context = new Context ( ) ;
}Créer des méthodes Get / Post / Put comme: Get Tous:
//GET /api/customers
[ HttpGet ]
public IEnumerable < Customer > GetCustomers ( )
{
return _context . Customers . ToList ( ) ;
}Obtenez-en un:
//GET /api/customers/1
[ HttpGet ]
public Customer GetCustomer ( int id )
{
var customer = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customer == null )
throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
return customer ;
}Créer:
//POST /api/customers
[ HttpPost ]
public Customer CreateCustomer ( Customer customer )
{
if ( ! ModelState . IsValid )
throw new HttpResponseException ( HttpStatusCode . BadRequest ) ;
_context . Customers . Add ( customer ) ;
_context . SaveChanges ( ) ;
return customer ;
}Mise à jour:
//PUT /api/customers/1
[ HttpPut ]
public void UpdateCustomer ( int id , Customer customer )
{
if ( ! ModelState . IsValid )
throw new HttpResponseException ( HttpStatusCode . BadRequest ) ;
var customerInDb = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customerInDb == null )
throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
customerInDb . Name = customer . Name ;
customerInDb . Birthdate = customer . Birthdate ;
customerInDb . IsSubscribedToNewsletter = customer . IsSubscribedToNewsletter ;
customerInDb . MembershipTypeId = customer . MembershipTypeId ;
_context . SaveChanges ( ) ;
}Supprimer:
//DELETE /api/customers/1
[ HttpDelete ]
public void DeleteCustomer ( int id )
{
var customerInDb = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customerInDb == null )
throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
_context . Customers . Remove ( customerInDb ) ;
_context . SaveChanges ( ) ;
}Tester avec Postman
Objets de domaine que nous supprimons les données que nous ne voulons pas être modifiées ou montrées. En forme de nos besoins. Stocker dans le dossier DTOS
Dans app_start, créez mappingprofile.cs:
public class MappingProfile : Profile
{
public MappingProfile ( )
{
Mapper . CreateMap < Customer , CustomerDto > ( ) ;
Mapper . CreateMap < CustomerDto , Customer > ( ) ;
}
}ajouter du mappeur à global.asax.cs
protected void Application_Start ( )
{
Mapper . Initialize ( c => c . AddProfile < MappingProfile > ( ) ) ;
//..
}Mettre à jour les actions du contrôleur:
//GET /api/customers
[ HttpGet ]
public IEnumerable < CustomerDto > GetCustomers ( )
{
return _context . Customers . ToList ( ) . Select ( Mapper . Map < Customer , CustomerDto > ) ;
} //GET /api/customers/1
[ HttpGet ]
public CustomerDto GetCustomer ( int id )
{
var customer = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customer == null )
throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
return Mapper . Map < Customer , CustomerDto > ( customer ) ;
} //POST /api/customers
[ HttpPost ]
public CustomerDto CreateCustomer ( CustomerDto customerDto )
{
if ( ! ModelState . IsValid )
throw new HttpResponseException ( HttpStatusCode . BadRequest ) ;
var customer = Mapper . Map < CustomerDto , Customer > ( customerDto ) ;
_context . Customers . Add ( customer ) ;
_context . SaveChanges ( ) ;
customerDto . Id = customer . Id ;
return customerDto ;
} //PUT /api/customers/1
[ HttpPut ]
public void UpdateCustomer ( int id , CustomerDto customerDto )
{
if ( ! ModelState . IsValid )
throw new HttpResponseException ( HttpStatusCode . BadRequest ) ;
var customerInDb = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customerInDb == null )
throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
Mapper . Map ( customerDto , customerInDb ) ;
_context . SaveChanges ( ) ;
} Dans app_start webapiconfig.cs Ajouter le registre
var settings = config . Formatters . JsonFormatter . SerializerSettings ;
settings . ContractResolver = new CamelCasePropertyNamesContractResolver ( ) ;
settings . Formatting = Formatting . Indented ; Corriger les résultats HTTP pour nos actions:
//GET /api/customers/1
[ HttpGet ]
public IHttpActionResult GetCustomer ( int id )
{
var customer = _context . Customers . SingleOrDefault ( c => c . Id == id ) ;
if ( customer == null )
return NotFound ( ) ;
return Ok ( Mapper . Map < Customer , CustomerDto > ( customer ) ) ;
} //POST /api/customers
[ HttpPost ]
public IHttpActionResult CreateCustomer ( CustomerDto customerDto )
{
if ( ! ModelState . IsValid )
return BadRequest ( ) ;
var customer = Mapper . Map < CustomerDto , Customer > ( customerDto ) ;
_context . Customers . Add ( customer ) ;
_context . SaveChanges ( ) ;
customerDto . Id = customer . Id ;
return Created ( new Uri ( Request . RequestUri + "/" + customer . Id ) , customerDto ) ;
} Postman: Get: https: // localhost: 44362 / api / films 200 ok
[
{
"id" : 1 ,
"name" : " Citizen Kane " ,
"genreId" : 3 ,
"dateAdded" : " 1900-01-01T00:00:00 " ,
"releaseDate" : " 1941-01-01T00:00:00 " ,
"numberInStock" : 4
},
{
"id" : 3 ,
"name" : " Rear Window " ,
"genreId" : 10 ,
"dateAdded" : " 1900-01-01T00:00:00 " ,
"releaseDate" : " 1954-01-01T00:00:00 " ,
"numberInStock" : 3
},
//.......
]Get: https: // localhost: 44362 / api / films / 7 200 ok
{
"id" : 7 ,
"name" : " The Good, the Bad and the Ugly " ,
"genreId" : 6 ,
"dateAdded" : " 1900-01-01T00:00:00 " ,
"releaseDate" : " 1966-01-01T00:00:00 " ,
"numberInStock" : 1
}Post: https: // localhost: 44362 / api / films 201 créé
{
"name" : " Life Is Beautiful " ,
"genreId" : 3 ,
"dateAdded" : " 1900-01-01T00:00:00 " ,
"releaseDate" : " 1997-01-01T00:00:00 " ,
"numberInStock" : 1
}Put: https: // localhost: 44362 / api / films / 11 204 pas de contenu
{
"name" : " Life Is Beautiful " ,
"genreId" : 3 ,
"dateAdded" : " 1900-01-01T00:00:00 " ,
"releaseDate" : " 1997-01-01T00:00:00 " ,
"numberInStock" : 5
}Supprimer: https: // localhost: 44362 / api / films / 12 204 pas de contenu
Affichage, ajoutez des classes, des données et de l'ID aux éléments. Et au script final:
< table id =" customers " < ---
class =" table table-borderless " >
< tr class =" danger " >
< th > Customers </ th >
....
....
< td >
< button data-customer-id =" @item.Id " < ---
class =" btn-link js-delete " < ---
>
Delete
</ button >
</ td >
.....
@section scripts{
< script >
$ ( document ) . ready ( function ( ) {
$ ( "#customers .js-delete" ) . on ( "click" , function ( ) {
var button = $ ( this ) ;
if ( confirm ( "sure to delete?" ) ) {
$ . ajax ( {
url : "/api/customers/" + button . attr ( "data-customer-id" ) ,
method : "DELETE" ,
success : function ( ) {
alert ( "success" ) ;
button . parents ( "tr" ) . remove ( ) ;
}
} ) ;
}
} ) ;
} ) ;
</ script >
} Ajouter BundleConfig.cs:
bundles . Add ( new ScriptBundle ( "~/bundles/bootstrap" ) . Include (
"~/Scripts/bootstrap.js" ,
"~/Scripts/bootbox.js" , //<--- here
"~/Scripts/respond.js"
) ) ;Implémentation en vue:
@section scripts{
< script >
$ ( document ) . ready ( function ( ) {
$ ( "#customers .js-delete" ) . on ( "click" , function ( ) {
var button = $ ( this ) ;
bootbox . confirm ( "sure to delete?" , function ( result ) {
if ( result ) {
$ . ajax ( {
url : "/api/customers/" + button . attr ( "data-customer-id" ) ,
method : "DELETE" ,
success : function ( ) {
alert ( "success" ) ;
button . parents ( "tr" ) . remove ( ) ;
}
} ) ;
}
} ) ;
} ) ;
} ) ;
</ script >
} Ajouter aux paquets: (et nous avons fusionné des paquets de tiers à lib. Dans _Layout.cshtml -> @Scripts.Render("~/bundles/lib") )
bundles . Add ( new ScriptBundle ( "~/bundles/lib" ) . Include (
"~/Scripts/jquery-{version}.js" ,
"~/Scripts/bootstrap.js" ,
"~/Scripts/bootbox.js" ,
"~/Scripts/respond.js" ,
"~/Scripts/DataTables/jquery.dataTables.js" , //<--
"~/Scripts/DataTables/dataTables.bootstrap.js" //<--
) ) ; bundles . Add ( new StyleBundle ( "~/Content/css" ) . Include (
"~/Content/bootstrap.css" ,
"~/content/datatables/css/dataTables.bootstrap.css" , //<-- style
"~/Content/site.css" ) ) ;En vue, les tables doivent avoir ID et THEAD, les balises TBODY. Enfin dans la section Script lorsque le document est prêt:
$ ( document ) . ready ( function ( ) {
$ ( "#customers" ) . DataTable ( ) ;
//...
} Dans JQuery DataTable Call:
$ ( document ) . ready ( function ( ) {
$ ( "#customers" ) . DataTable ( {
ajax : {
url : "/api/customers" ,
dataSrc : ""
} ,
columns : [
{
data : "name" ,
render : function ( data , type , customer ) {
return "<a href='/customers/edit/'" + customer . id + "'>" + customer . name ;
}
} ,
{
data : "membershipType.name"
} ,
{
data : "id" ,
render : function ( data ) {
return "<button class='btn-link js-delete' data-customer-id=" + data + ">Delete</button>" ;
}
}
]
} ) ; Étape 1: Créer DTO, Étape 2: Ajouter DTO au parent DTO Étape 3.Map dans le profil de mappage Étape 4: Ajouter au contrôleur (._appdbcontext.Customers.include (c => c.membershipType) .tolist () ..) Étape 5: Ajouter à la colonne de vue comme:
{
data : "membershipType.name"
} , Affectez la table à la variable et utilisez-la dans la méthode de suppression:
< script >
$ ( document ) . ready ( function ( ) {
var table //<--
= $ ( "#customers" ) . DataTable ( {
ajax : {
url : "/api/customers" ,
dataSrc : ""
} ,
columns : [
{
data : "name" ,
render : function ( data , type , customer ) {
return "<a href='/customers/edit/'" + customer . id + "'>" + customer . name ;
}
} ,
{
data : "membershipType.name"
} ,
{
data : "id" ,
render : function ( data ) {
return "<button class='btn-link js-delete' data-customer-id=" + data + ">Delete</button>" ;
}
}
]
} ) ;
$ ( "#customers" ) . on ( "click" , ".js-delete" , function ( ) {
var button = $ ( this ) ;
bootbox . confirm ( "Are you sure you want to delete this customer?" , function ( result ) {
if ( result ) {
$ . ajax ( {
url : "/api/customers/" + button . attr ( "data-customer-id" ) ,
method : "DELETE" ,
success : function ( ) {
///<--- here
table . row ( button . parents ( "tr" ) )
. remove ( ) . draw ( ) ;
}
} ) ;
}
} ) ;
} ) ;
} ) ;
</ script > 
Toute la logique est intégrée (voir commit pour les fichiers et les détails)
Ajouter [autoriser] l'attribut aux actions du contrôleur ou au-dessus du contrôleur pour restreindre toutes les actions
FilterConfig.cs:
filters . Add ( new AuthorizeAttribute ( ) ) ;Cela désactive tous les contrôleurs pour les utilisateurs non autorisés, mais vous pouvez ajouter [allowanonymous] aux contrôleurs ou actions pour permettre à l'accès
Se dans la base de données : pour maintenir la cohérence du projet sur différents scénarios de travail, ajoutez-les à une migration
Créer des vues distinctes pour les invités et les utilisateurs autorisés
Dans Controller:
public ViewResult Index ( int ? pageIndex , string sortBy )
{
if ( User . IsInRole ( RoleName . CanManageMovies ) )
return View ( "List" ) ;
return View ( "ReadOnlyList" ) ;
} Pour désactiver d'autres actions, accédez à cet attribut: [Authorize(Roles = RoleName.CanManageMovies)]
Créez un modèle pour garder les rôles rolename.cs:
public const string CanManageMovies = "CanManageMovies" ; Pour ajouter des champs personnalisés à l'utilisateur: Ajoutez l'hélice à la fois à la classe utilisateur de l'application et à ViewModel de la vue. Ajoutez également un nouvel accessoire pour enregistrer la section Affectation des actions
Activer SSL dans les propriétés, ajouter un filtre
filters . Add ( new RequireHttpsAttribute ( ) ) ;Obtenez AppID et AppSecret sur Facebook, Google ... Insérer dans startup.auth.cs
app . UseFacebookAuthentication (
appId : "id" ,
appSecret : "secret" ) ;Ajoutez tous les accessoires personnalisés au formulaire de connexion externe et à ViewModel. Initialiser dans le contrôleur de connexion externe

Dans Nuget, installez Glimpse.mvc5 et Glimpse.ef6 allez sur /glimse.axd et activez
Désactiver la mise en cache: [OutputCache(Duration = 0, VaryByParam = "*", NoStore = true)]
Activer la mise en cache:
[OutputCache(Duration=50,Location=OutputCacheLocation.Server,VaryByParam="genre")]
dans l'action du contrôleur
if ( MemoryCache . Default [ "Genres" ] == null )
{
MemoryCache . Default [ "Genres" ] = _appDbContext . Genres . ToList ( ) ;
}
var genres = MemoryCache . Default [ "Genres" ] as IEnumerable < Genre > ; dans web.config dans System.web
Nous allons ajouter une fonctionnalité de location à notre application Créer DTO: NewRentalDTO:
public class NewRentalDto
{
public int CustomerId { get ; set ; }
public List < int > MovieIds { get ; set ; }
}Créer un modèle: location, ajouter au contexte et exécuter une migration
public class Rental
{
public int Id { get ; set ; }
[ Required ]
public Customer Customer { get ; set ; }
[ Required ]
public Movie Movie { get ; set ; }
public DateTime DateRented { get ; set ; }
public DateTime ? DateReturned { get ; set ; }
}Plus de détails sur les commits. (Typeahead utilisée, sanghound pour la saisie semi-automatique)
Cliquez avec le bouton droit
PM> update-database -script -SourceMigration:SeedUsers
cibler le mig pour durer. Vous avez une requête SQL de votre DB maintenant
Dans web.config <appSettings key="value"></appSettings> ConfigurationManager.AppSettings["Key"] créez un autre fichier config < <appSettings configSource="AppSettings.config"></appSettings> config Vous devez le convertir pour vos besoins manuellement
dans web.config Ajouter à <system.web>
<customErrors mode="On"></customErrors>
ON: Activer Everywhere Remote: Désactiver sur localhost
Personnaliser dans les vues> Erreur partagée.cshtml
dans web.config Ajouter à <system.web> >> <customErrors>
< system .web>
< customErrors mode = " On " >
< error statusCode = " 404 " redirect = " ~/404.html " />
</ customErrors >
<!-- ..... -->
</ system .web> n web.config Ajouter à <system.webServer>
< httpErrors errorMode = " Custom " >
< remove statusCode = " 404 " />
< error statusCode = " 404 " path = " 404.html " responseMode = " File " />
</ httpErrors >Custom: Activer Everywhere DetailledLocalonly: Désactiver sur localhost
Nuget> Elmah
Enregistreur d'exception. Accès par /elmah.axd
Par défaut, il enregistre les journaux à la mémoire, mais avec une petite configuration, nous pourrions avoir ces exceptions sur toutes sortes de bases de données
pour accéder à distance, ajoutez ceci à Elmah
< authorization >
< allow roles = " admin,user2,user3,... " />
< deny users = " * " />
</ authorization >MERCI!!!