Je suis le Microsoft Contoso University Tutorial pour apprendre MVC.L'itinéraire personnalisé ne fonctionne pas avec l'itinéraire mvc par défaut
Jusqu'à présent, j'ai créé 3 modèles
- Cours
- inscription
- étudiant
Et j'ai 2 contrôleurs
- HomeController
- StudentController
Je peux afficher une liste d'étudiants, des détails sur les étudiants, y compris les cours et les notes qu'ils ont dans les cours, modifier les détails de l'étudiant, et ajouter de nouveaux étudiants.
À ce stade, je voulais en savoir plus sur le routage depuis que j'avais utilisé par défaut Carte Route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
J'ai une base de données des étudiants qui ont tous les noms de famille uniques. Je suis conscient que cela n'est normalement pas recommandé car les noms de famille ne sont pas uniques, mais cela fonctionne pour ce petit projet d'apprentissage. Donc, ce que je voulais atteindre était de pouvoir taper /students/{action}/{lastname}
et voir les détails sur l'étudiant. J'ai donc créé une nouvelle méthode d'action dans mon contrôleur d'étudiant.
public ActionResult Grab(string studentName)
{
if (studentName == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var student = db.Students.FirstOrDefault(x => x.LastName.ToLower() == studentName.ToLower());
if (student == null)
return HttpNotFound();
return View(student);
}
Et j'ai ajouté une nouvelle route dans mon RouteConfig.cs fichier
//Custom route
routes.MapRoute(
name: null,
url: "{controller}/{action}/{studentName}",
defaults: new { controller = "Student", action = "Grab", id = UrlParameter.Optional }
);
Et enfin, je créé une nouvelle vue appelée Grab qui montre des détails sur l'étudiant.
Maintenant, quand je tape /student/grab/Norman
il me donne les détails de l'étudiant avec le nom Norman
C'est grand. Mais maintenant j'ai un problème. Lorsque j'essaie d'utiliser certaines de mes URL d'origine comme /Student/Details/1
, elles ne fonctionnent plus. Je reçois une erreur 400.
La première chose que je ne faisais que passer ma route par défaut au-dessus de la route personnalisée que j'ai fait
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
//Custom route
routes.MapRoute(
name: null,
url: "{controller}/{action}/{studentName}",
defaults: new { controller = "Student", action = "Grab", id = UrlParameter.Optional }
);
Et cela résout ce problème, mais provoque une erreur 400 sur mon itinéraire grab travail auparavant. Comment puis-je utiliser les deux en même temps sans avoir une erreur 400?
Voici fichier mes RouteConfig.cs plein
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace ContosoUniversity
{
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 }
);
//Custom route
routes.MapRoute(
name: null,
url: "{controller}/{action}/{studentName}",
defaults: new { controller = "Student", action = "Grab", id = UrlParameter.Optional }
);
}
}
}
Voici fichier mon StudentController.cs ensemble
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ContosoUniversity.DAL;
using ContosoUniversity.Models;
namespace ContosoUniversity.Controllers
{
public class StudentController : Controller
{
private SchoolContext db = new SchoolContext();
// GET: Student
public ActionResult Index()
{
return View(db.Students.ToList());
}
// GET: Student/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Student student = db.Students.Find(id);
if (student == null)
{
return HttpNotFound();
}
return View(student);
}
public ActionResult Grab(string studentName)
{
if (studentName == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var student = db.Students.FirstOrDefault(x => x.LastName.ToLower() == studentName.ToLower());
if (student == null)
return HttpNotFound();
return View(student);
}
// GET: Student/Create
public ActionResult Create()
{
return View();
}
// POST: Student/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student)
{
try
{
if (ModelState.IsValid)
{
db.Students.Add(student);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(student);
}
// GET: Student/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Student student = db.Students.Find(id);
if (student == null)
{
return HttpNotFound();
}
return View(student);
}
// POST: Student/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var studentToUpdate = db.Students.Find(id);
if (TryUpdateModel(studentToUpdate, "",
new string[] { "LastName", "FirstMidName", "EnrollmentDate" }))
{
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
return View(studentToUpdate);
}
// GET: Student/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Student student = db.Students.Find(id);
if (student == null)
{
return HttpNotFound();
}
return View(student);
}
// POST: Student/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Student student = db.Students.Find(id);
db.Students.Remove(student);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Je vais vous donner d'autres détails nécessaires.Encore une fois, je veux être en mesure de taper http://localhost:49706/Student/Details/1
ou http://localhost:49706/Student/Grab/Alexander
et obtenir les mêmes détails exacts puisque Alexander est a la idEtudiant 1.
Question rapide. Ma structure url doit maintenant être/Student/Details? Id = 1 plutôt que Student/Details/1 ce qui me donne une erreur de 400. Savez-vous pourquoi c'est? – onTheInternet
@onTheInternet, Cela ne devrait pas être. mettre à jour les actions pour utiliser le même nom que dans le modèle 'studentId' ou ce que vous décidez d'utiliser une fois qu'elles sont identiques. Notez comment le nom a été changé de 'id' à' studentId' dans la réponse pour correspondre au modèle de route. Toutes les actions nécessitant l'identifiant doivent être modifiées pour correspondre. Ou vous pourriez revenir à les refaire tous, une fois le modèle mis à jour ainsi – Nkosi
J'ai copié votre code exactement et cela a corrigé mon problème. Je ne sais pas ce que j'avais tort. Une dernière question. ma vue d'index pour mon contrôleur d'étudiant montre un lien incorrect pour des détails. Donc plutôt que le lien va/student/Details/1 il montre/Student/Details? Id = 1 qui me donne un 400 quand je vais à lui. Je ne suis pas sûr comment résoudre ce problème parce que mon lien d'action ressemble à ceci @ Html.ActionLink ("Détails", "Détails", nouveau {id = item.ID}) – onTheInternet