Home > Back-end >  How to make a button click in ASP.NET Core 3.1
How to make a button click in ASP.NET Core 3.1

Time:11-12

Please help me to solve this error. If click Save button display the following error. I am using ASP.NET Core 3.1 with Entity Framework Core.

An unhandled exception occurred while processing the request. InvalidOperationException: The view 'Save' was not found. The following locations were searched:

/Views/Home/Save.cshtml
/Views/Shared/Save.cshtml

InvalidOperationException: The view 'Save' was not found. The following locations were searched: /Views/Home/Save.cshtml /Views/Shared/Save.cshtml

Controller: HomeController

public IActionResult Index()
{
      CascadingModel model = new CascadingModel();
      model.Countries = (from customer in this.Context.Countries
                         select new SelectListItem
                         {
                             Value = customer.CountryId.ToString(),
                             Text = customer.CountryName
                         }).ToList();
      return View(model);
}

[HttpPost]
public ActionResult Index(int countryId, int stateId, int cityId)
{
      CascadingModel model = new CascadingModel();
      model.Countries = (from customer in this.Context.Countries
                         select new SelectListItem
                         {
                             Value = customer.CountryId.ToString(),
                             Text = customer.CountryName
                         }).ToList();

      model.States = (from customer in this.Context.States
                      where customer.CountryId == countryId
                      select new SelectListItem
                      {
                          Value = customer.StateId.ToString(),
                          Text = customer.StateName
                      }).ToList();

      model.Cities = (from customer in this.Context.Cities
                      where customer.StateId == stateId
                      select new SelectListItem
                      {
                          Value = customer.CityId.ToString(),
                          Text = customer.CityName
                      }).ToList();

      return View(model);
}

[HttpPost]
[ActionName("Save")]
[ValidateAntiForgeryToken]
public IActionResult Save(CascadingModel model)
{
      if (ModelState.IsValid)
      {
          var newstaffrecords = new StaffDetailVM()
          {
              StaffId = model.StaffId,
              StaffName = model.StaffName,
              CountryName = model.CountryName,
              StateName = model.StateName,
              CityName = model.CityName,

          };
          this.Context.Stafftbl.Add(newstaffrecords);
          this.Context.SaveChanges();
      }

      return View(model);
}

View: Index.cshtml

<form asp-controller="Home" method="post">
<div >
    <div >
        <div asp-validation-summary="ModelOnly" ></div>
        <div >
            <label asp-for="StaffId" ></label>
            <input asp-for="StaffId"  />
            <span asp-validation-for="StaffId" ></span>
        </div>
        <div >
            <label asp-for="StaffName" ></label>
            <input asp-for="StaffName"  />
            <span asp-validation-for="StaffName" ></span>
        </div>
        
        <div >
            <label asp-for="CountryId" ></label>
            <select id="ddlCountries" name="CountryName" asp-for="CountryId" asp-items="Model.Countries" >
               <option value="">--Please select--</option>
            </select>
            <span asp-validation-for="CountryId" ></span>
        </div>
         <div >
            <label asp-for="StateId" ></label>
            <select id="ddlStates" name="StateName" asp-for="StateId" asp-items="Model.States" >
               <option value="">--Please select--</option>
             </select>
            <span asp-validation-for="StateId" ></span>
        </div>
        <div >
            <label asp-for="CityId" ></label>
             <select id="ddlCities" name="CityName" asp-for="CityId" asp-items="Model.Cities" >
                  <option value="">--Please select--</option>
              </select>
            <span asp-validation-for="CityId" ></span>
        </div>
        <div >
            <button type="submit" asp-action="Save" >Save</button>
        </div>
      </div>
   </div>
</form>

CodePudding user response:

If you don't follow the ASP.Net MVC patterns (calling the view just like the action that returns it. In your case your View should be called Save.cshtml), you need to specify the name of the View you want to return.

Solution:

It's pretty easy to solve, just add the "Index" as a parameter for the "return View(...) line.

[HttpPost]
[ActionName("Save")]
[ValidateAntiForgeryToken]
public IActionResult Save(CascadingModel model)
{
      if (ModelState.IsValid)
      {
          var newstaffrecords = new StaffDetailVM()
          {
              StaffId = model.StaffId,
              StaffName = model.StaffName,
              CountryName = model.CountryName,
              StateName = model.StateName,
              CityName = model.CityName,

          };
          this.Context.Stafftbl.Add(newstaffrecords);
          this.Context.SaveChanges();
      }

      return View("Index", model);
}

Here's a link to read some documentation about how to Name things to make it happen automatically, and how to use that "return View(...)" method to return any views you need: enter image description here

Reason:1:

If you entounter the error before your controller public IActionResult Save(CascadingModel model) get call. In that case you might need to set your form atrribute like this instead ofIts because you are usingexplicite routing attributeas[ActionName("Save")]`

Reason:2:

However, if you are getting the error in this likereturn View(model); then the cause is different.

In this case, you may have two scenario, After you saving the information either you want to go to IActionResult Save(CascadingModel model) view in that case you have to redirect to that view as per its methods signature for instance, your save view may need this model to pass CascadingModel model = new CascadingModel(); in that case you have to redirect as below:

return RedirectToAction("Index", model); //Or

return View("Index", model);

Note: Keep in mind this model View("Index", model) should same type as of your Index CascadingModel model = new CascadingModel();.

Output:

enter image description here

Reason:3:

In this case, after adding new stuff you may want to display all the list of staff in a List View Page In that case you may redirect to that List Page therefore, you can do as following: Just redirect to that List pagge return RedirectToAction("StaffList");

        [HttpPost]
        [ActionName("Save")]
        [ValidateAntiForgeryToken]
        public IActionResult Save(CascadingModel model)
        {
            if (ModelState.IsValid)
            {
                var newstaffrecords = new StaffDetailVM()
                {
                    StaffId = model.StaffId,
                    StaffName = model.StaffName,
                    CountryName = model.CountryName,
                    StateName = model.StateName,
                    CityName = model.CityName,

                };
                //  this.Context.Stafftbl.Add(newstaffrecords);
               // this.Context.SaveChanges();
            }

            return RedirectToAction("StaffList");
        }

Sample List Page Action:

public IActionResult StaffList()
        {
            var staffList = new List<StaffDetailVM>()
            {
                new StaffDetailVM() { StaffId=101,StaffName="Douda", CountryName = "USA",StateName ="New Jersy", CityName ="City In NJ" },
                new StaffDetailVM() { StaffId=102,StaffName="Kiron", CountryName = "UK",StateName ="London", CityName ="Hampe Shire" },
                new StaffDetailVM() { StaffId=103,StaffName="Farid", CountryName = "Canada",StateName ="Alberta", CityName ="Edmonton" },
                new StaffDetailVM() { StaffId=101,StaffName="Jhon", CountryName = "Australia",StateName ="Adelate", CityName ="West Adelate" },
               


            };
            return View(staffList);
        }

Output:

enter image description here

Hope either of above scenario will help to resolve your issue.

CodePudding user response:

If your view is in Index.cshtml on your Home folder as you mention it on your comment, you should return it like that:

return View("~/Views/Home/Index.cshtml", model);
  • Related