0

I just started learning MVC and I was trying to pass studentId as a parameter to an edit page. By default, when you click on the Edit link, it goes to:

 localhost:63348/student/Edit/5 

but it doesn't work. it gives me this error

The parameters dictionary contains a null entry for parameter 'StudentId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'WebApplication1.Controllers.StudentController'.`

But if I change it manually to:

 localhost:63348/student/Edit?studentid=5

it then works. Should they mean the same thing and work almost the same way?

Here's my controller:

public IList<Student>studentList = new List<Student>{
            new Student() { StudentId = 1, StudentName = "John", Age = 18 } ,
            new Student() { StudentId = 2, StudentName = "Steve",  Age = 21 } ,
            new Student() { StudentId = 3, StudentName = "Bill",  Age = 25 } ,
            new Student() { StudentId = 4, StudentName = "Ram" , Age = 20 } ,
            new Student() { StudentId = 5, StudentName = "Ron" , Age = 31 } ,
            new Student() { StudentId = 6, StudentName = "Chris" , Age = 17 } ,
            new Student() { StudentId = 7, StudentName = "Rob" , Age = 19 }
        };

    [Route("Edit/{studentId:int")]
    public ActionResult Edit(int StudentId)
    {
        //Get the student from studentList sample collection 
        var std = studentList.Where(s => s.StudentId == StudentId).FirstOrDefault();

        return View(std);
    }

Tried adding a specific route config but didn't work either:

routes.MapRoute(
            name: "StudentEdit",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Student", action = "Edit", id = UrlParameter.Optional }
        );
El Dj
  • 385
  • 1
  • 7
  • 22
  • 1
    Two things. First, your route is malformed. `[Route("Edit/{studentId:int")]` You are missing the closing `}`. Secondly, your route parameter is not identical to the name of the method parameter. Case matters. –  Oct 25 '17 at 13:20
  • 1
    @Amy, The `DefaultModelBinder` is **not** case sensitive –  Oct 28 '17 at 08:22
  • You need to add `routes.MapMvcAttributeRoutes();` in your `RouteConfig.cs` before `routes.MapRoute(...)` to enable attribute routing, and add `[RoutePrefix("Student")]` to your controller definition –  Oct 28 '17 at 08:32

1 Answers1

1

You need to add attribute [FromUri] and correct the compiling issues (Provide closing bracket } and the argument name is not same.

[Route("Edit/{studentId:int}")]
    public ActionResult Edit([FromUri] int studentId)
    {
        //Get the student from studentList sample collection 
        var std = studentList.Where(s => s.StudentId == StudentId).FirstOrDefault();

        return View(std);
    }
S M
  • 3,133
  • 5
  • 30
  • 59
  • FromUri is giving me an error. I changed the route making sure it matched in terms of case `[Route("Edit/{StudentId:int}")]` but still not working – El Dj Oct 25 '17 at 13:30
  • 1
    @ElDj have you enabled attribute routing? –  Oct 25 '17 at 13:32
  • use it like this `[Route("Edit/{StudentId}")]` – S M Oct 25 '17 at 13:33
  • Enabled attribute routing and removed the `int` part. Now, I'm getting a resource not found error – El Dj Oct 25 '17 at 13:37
  • You're a step in the right direction. Also add `[HttpGet]` (or whichever is the appropriate verb for your case). –  Oct 25 '17 at 13:45
  • Is't it supposed to be `[HttpGet]` by default? It still gives me the resource not found error – El Dj Oct 25 '17 at 13:51
  • No. Convention-based routing uses the method name to determine the verb. `GetFoos` vs `PostFoos` for instance. If you're using attribute routing, the action name can still be used, however, it defaults to [POST](https://stackoverflow.com/questions/23686841/is-there-a-default-verb-applied-to-a-web-api-apicontroller-method) –  Oct 25 '17 at 13:57
  • If I enable attribute routing, I get resource not found for both `(/id)` and `(?id=)`. When I disable it, `(?id=)` works but not `(/id)`. – El Dj Oct 25 '17 at 14:08
  • Changed my parameter name to `id` and it worked. Why didn't StudentId work tho? I even changed my routeconfig to `url: "{controller}/{action}/{StudentId}"` but was still not working – El Dj Oct 25 '17 at 14:21
  • `[FromUri]` is for web-api (and its the default for a GET with a simple parameter anyway) –  Oct 28 '17 at 08:24