Home > Blockchain >  How to get the TextBox value in controller action in asp.net core mvc application without using jque
How to get the TextBox value in controller action in asp.net core mvc application without using jque

Time:10-14

I am a newbie in asp.net core mvc. Trying to make a simple update page where the model (coming from another data service) is bound with a table. On each row there is a update button. There are some fields which are mapped to the text box and are editable.

I want to get the editable values in text box within the controller without using jquery or ajax. I am sure there must be a way in plain asp.net core capabilities.

Model:

public class Employee
{
    public string Name { get; set; }
    public string Location { get; set; }
}

View:

@model IEnumerable<AspNetCoreMVC.Models.Employee>

@{
    ViewData["Title"] = "Home";
}

<table  style="width:fit-content">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(Model => Model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(Model => Model.Location)
            </th>
            <th>

            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @item.Name
                </td>
                <td>
                    @Html.TextBoxFor(m => item.Location)
                </td>
                <td>
                    @Html.ActionLink("Update","UpdateAction","Home",new { updatedLocation = item.Location })
                </td>
            </tr>
        }
    </tbody>
</table>

Controller:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using AspNetCoreMVC.Models;

namespace AspNetCoreMVC.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            var employees = new List<Employee>();
            employees.Add(new Employee { Name="Abcd", Location="abcdLocation1"});
            employees.Add(new Employee { Name = "Efgh", Location = "EfghLocation2" });
            return View(employees);
        }

        public IActionResult UpdateAction(string updatedLocation)
        {
            var employees = new List<Employee>();
            employees.Add(new Employee { Name = "Abcd", Location = "abcdLocation1" });
            employees.Add(new Employee { Name = "Efgh", Location = "EfghLocation2" });
            return View("Index", employees);
        }
        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

Currently I only get the same value as bound by the cell template textbox. How can I make sure the changed text in the textbox location is received in the controller please ?

CodePudding user response:

In my case this worked when I used the @Html.EditorFor() helper instead of the @Html.TextBoxFor() helper, with setting the name attribute.

Therefore, try the following:

<tbody>
    @foreach (var item in Model)
    {
        @using (Html.BeginForm("UpdateAction", "Home"))
        {                
            <tr>
                <td>
                    @item.Name
                </td>
                <td>     
                    @* Setting the `name` attribute explicitly *@               
                    @Html.EditorFor(m => item.Location, "name", "updatedLocation")
                </td>
                <td>
                    <div><input type="submit" value="Update" /></div>                  
                </td>
            </tr>
        }
    }
</tbody>

Because of the binding context will already have the updatedLocation name, you don't need to define it in the Html.BeginForm().

And the [HttpPost] attribute should be added to theUpdateAction() action method declaration:

[HttpPost]
public IActionResult UpdateAction(string updatedLocation)
{
    ...
}

NOTE: An additional option is using the <input> tag instead of @Html.EditorFor() helper:

<input id="updatedLocation" name="updatedLocation" type="text" value="@item.Location" />

CodePudding user response:

Try to add a form outside <tr>:

<tbody>
        @foreach (var item in Model)
        { 
        <form asp-action="UpdateAction" asp-controller="Home" >
            <tr>
                <td>
                    @item.Name
                </td>
                <td>
                    @Html.TextBoxFor(m => item.Location)
                </td>
                <td>
                    <input type="submit" value="Update" />
                </td>
            </tr>
        </form>
        }
    </tbody>

And because name attribute bind with the property name in action,try to change your action like this:

public IActionResult UpdateAction(string Location)
        {
            var employees = new List<Employee>();
            employees.Add(new Employee { Name = "Abcd", Location = "abcdLocation1" });
            employees.Add(new Employee { Name = "Efgh", Location = "EfghLocation2" });
            return View("Index", employees);
        }
  • Related