Shax
Shax

Reputation: 4307

How to redirect a view to another action on the same Controller

I have a controller called StudentController, Index.cshtml and central layout.cschtml,

I am doing front end development after very long time and working on the frontend on asp.net mvc is quiet a challange for me now, so please forgive me if something is wrong.

What I am trying to achieve is that when I am running my application it runs perfectly find, but when I click the link Student it successfully goes to the Student Index view and hit the Index method in the StudentController.

But when I click on the Create New link on the Index view then it gives error (see at the bottom) , can someone guide what I am doing wrong....

StudentController

public StudentController(){}
public ActionResult Index()
{            
    var students =_studentDb.GetAll();            
    return View(students);
}

[HttpPost]
public ActionResult Create(Student student)
{
    var result = _studentDb.Insert(student);
    return View("Create");
}

_layout.chtml

 <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", new { Controller = "Home", Area = "Common" })</li>                    
                    <li>@Html.ActionLink("Student", "Index", new { Controller = "Student", Area = "User" })</li>
                    <li>@Html.ActionLink("New Student", "Index", new { Controller = "CreateStudent", Area = "User" })</li>
                </ul>

Index.chtml

@model IEnumerable<Student>

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

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create",new {Controller="Student",Area="User" })        
</p>
<table class="table">
    <tr>        
        <th>
            @Html.DisplayNameFor(model => model.FirstName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MiddleName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.LastName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Gender)
        </th>        
        <th>
            @Html.DisplayNameFor(model => model.FirstNameAr)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MiddleNameAr)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.LastNameAr)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>        
        <td>
            @Html.DisplayFor(modelItem => item.FirstName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.MiddleName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>        
        <td>
            @Html.DisplayFor(modelItem => item.FirstNameAr)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.MiddleNameAr)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastNameAr)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

Error

Server Error in '/' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

Requested URL: /User/Student/Create

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1055.0

Upvotes: 0

Views: 3995

Answers (4)

espCoder
espCoder

Reputation: 56

First you need two methods on your controller, one for the GET and one for the POST. You only have the POST.

The GET will return the Create View that you have here, so get change the HttpPost attribute.

[HttpGet]
public ActionResult Create()
{
  return View("Create");
}

If you want to Controller Action A to return Controller Action B, return RedirectToAction() instead of View()

Upvotes: 1

LateshtClick.com
LateshtClick.com

Reputation: 616

change code like this

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

[HttpPost] 
public ActionResult Create(Student student)
{
     var result = _studentDb.Insert(student); 
     return View(); 
}

Upvotes: 2

Mark Sowul
Mark Sowul

Reputation: 10600

Generally you need two actions:

  1. a GET action that shows the screen where the user will enter the values needed to create the new entity. This will have a form, which when submitted goes to the...
  2. POST action which accepts the form submission, checks the anti-forgery token, and does the actual data manipulation (adds the user into the database). An additional best practice is to then Redirect to a GET action (e.g. RedirectToAction back to the Index action) to avoid double posting (https://en.wikipedia.org/wiki/Post/Redirect/Get)

You only have the POST action...you can't link to that, you need to submit it as a form. So you need to create the GET action as well.

Upvotes: 1

Ceshion
Ceshion

Reputation: 706

You're getting an error because you're generating an <a> tag to a post action. You can only access post actions through a form post or ajax in javascript. If you're trying to link to another view like that, you'll want to remove the [HttpPost] attribute. Additionally, it seems that you'd want to pass your result into your Create view like: return View(result) (using this overload because your view has the same name as your action). Additionally, your Create action has a Student parameter, but you aren't passing values into it. I'd recommend a structure more like the following:

public IActionResult Create() 
{
    var student = new Student();
    return View(student)
}

[HttpPost]
public IActionResult Create(Student student)
{
    _studentDb.Add(student);
    _studentDb.SaveChanges();
    // Do whatever you like to finish this action
}

And then your Create view should contain a form for entering data about the student that would post to /User/Student/Create.

Upvotes: 2

Related Questions