ASP .Net MVC Contoso University如何根据姓氏获取学生详细信息

时间:2017-04-20 16:47:28

标签: c# asp.net-mvc entity-framework

我正在尝试学习MVC,我正在跟随位于here的Contoso大学教程

我已成功构建了一个包含学生,课程和注册数据库的项目。目前我有3个型号,

  1. 注册
  2. 学生
  3. 和2个控制器

    1. 的HomeController
    2. StudentController
    3. 目前,我的路由是您使用MVC项目获得的默认路由。

              routes.MapRoute(
                  name: "Default",
                  url: "{controller}/{action}/{id}",
                  defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
      

      这适用于根据StudentID

      获取学生详细信息

      所以网址

      http://localhost:49706/Student/Details/1

      返回此信息 Student Details

      这很好用,但我试图更深入地了解路由。我想创建一个新视图,根据最后一个名称而不是学生ID显示学生详细信息。是的,我知道在现实世界中,这不是一个好主意,因为姓氏不是唯一的,但这对于这个演示很好,因为我的数据库不会变大,我知道所有姓氏目前都是独一无二的。

      我做的第一件事是在我的StudentController中创建一个新的动作结果

      public ActionResult Grab(string studentName)
      {
          if(studentName == null)
          {
              return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
          }
          Student student = db.Students.Find(studentName);
          if(student == null)
          {
              return HttpNotFound();
          }
          return View(student);
      }
      

      我做的第二件事是右击“Grab”并添加了一个视图。我将视图名称称为“Grab”。将模板设置为“列表”。将Model Class设置为'Student(ContosoUniversity.Models)'。和DataContextClass为'SchoolContext(ContosoUniversity.DAL)'。

      Add View

      我打电话给你 http://localhost:49706/Student/Grab

      我得到的400错误就像我在控制器中写的一样。但是当我尝试以下网址时

      http://localhost:49706/Student/Grab/Alexander

      我还得到另外400个错误。我不确定我遗漏了什么。我可以帮忙吗。

      这是我的数据库的样子

      Database

      我想要做的就是能够输入以下网址 http://localhost:49706/Student/Grab/ {名字}

      并显示具有匹配姓氏的学生的详细信息。

      感谢您的时间

      修改

      更新了ActionResult Grab

      public ActionResult Grab(string studentName)
      {
          if(studentName == null)
          {
              return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
          }
          Student student = db.Students.Where(student => student.LastName.Contains(studentName)).FirstOrDefault();
          if (student == null)
          {
              return HttpNotFound();
          }
          return View(student);
      }
      

      整个学生管理员

      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);
                  }
                  Student student = db.Students.Where(student => student.LastName.Contains(studentName)).FirstOrDefault();
                  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);
              }
          }
      }
      

      感谢到目前为止的建议我现在有一个页面返回。但是,没有加载任何数据。这是一张照片 Almost working

      以下是视图的代码

      @model ContosoUniversity.Models.Student
      
          @{
              ViewBag.Title = "Grab";
          }
      
          <h2>Grab</h2>
      
          <p>
              @Html.ActionLink("Create New", "Create")
          </p>
          <table class="table">
              <tr>
                  <th>
                      @Html.DisplayNameFor(model => model.LastName)
                  </th>
                  <th>
                      @Html.DisplayNameFor(model => model.FirstMidName)
                  </th>
                  <th>
                      @Html.DisplayNameFor(model => model.EnrollmentDate)
                  </th>
                  <th></th>
              </tr>
      
          </table>
      

3 个答案:

答案 0 :(得分:2)

你的问题是路由。当您请求http://localhost:49706/Student/Grab/{LastName}时,参数studentName正在解析为null,因此您的BadRequestResponse。

您的网址中的模式与默认的ASP.NET MVC路由模式匹配,但它将无法绑定参数的值,因此MVC将正确命中控制器并执行操作,但参数将为null。

您有几个选择:

  

映射路线

您可以将其添加到路由配置文件:RouteConfig.cs目录中的App_Start

//Add your own route
routes.MapRoute(
    name: null,
    url: "{controller}/{action}/{studentName}",
    defaults: new { controller = "Student", action = "Grab", id = UrlParameter.Optional }
);

此调用应在调用映射默认路由之前进行。现在,您将能够从路径数据中获取studentName参数的值。

  

更改网址

您可以通过请求将您的页面添加为新路线来调用相同的操作:

http://localhost:49706/Student/Grab?studentName={LastName}

这里将有效地处理参数。

关于从数据库中提取学生,如果只想匹配完整的姓氏,我会在操作中使用此代码:

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

让我知道它对你有用。

希望这有帮助!

答案 1 :(得分:0)

你的第一个错误:

db.Students.Find(studentName); // This one expects an student object not string

所以你需要使用Where linq扩展名,这样你就可以用这样的姓氏过滤你的学生表:

Student student = db.Students.Where(student => student.LastName.Contains(studentName)).FirstOrDefault(); // Im using contains instead of equals to match substrings

答案 2 :(得分:0)

我假设你是从Index视图中尝试这样做的。所以因为你的Grab ActionResult期待一个名为studentName的参数(可能想要重命名为与lastName对应的内容)出于可维护性的目的).. Index视图上的操作链接需要如下所示:

@Html.ActionLink("Details by Last Name", "Grab", "Student", new{studentName = item.LastName}, null)
// I assume `item` because if it's in your Index view you are looping to get each user in their own row..

既然你明白使用一个人的姓是一个坏主意,因为它不是唯一的...但在这个例子中它是..没有必要使用.Contain()方法..你正在寻找一个人,因此您应该使用.SingleOrDefault()

public ActionResult Grab(string studentName)
{
    // in my experience.. when you're checking a string variable to see if 
    // it is null.. use string.IsNullOrWhiteSpace.. because even though what
    // you're using checks for null.. it doesn't check for white space..


    if(studentName == null) // so change this to if(string.IsNullOrWhiteSpace(studentName))
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    Student student = db.Students.SingleOrDefault(student => student.LastName.ToLower() == studentName.ToLower()); // convert the comparison strings to all lower case.. hence the the `.ToLower()` methods for more reliable comparison

    if (student == null)
        return HttpNotFound();

    return View(student);
}

希望这有帮助。