You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用表单将视图数据/模型传递至ASP.NET Core控制器Update方法

问题描述

在ASP.NET Core项目中,需要将Index视图中的TblMatHang模型数据传递至HomeController的Update动作方法,以此更新对应商品的信息,修改其属性值并保存后返回视图展示在下方表格中。尝试过嵌套表单和JavaScript,但均未成功或产生诸多问题。


Index.cshtml视图代码

@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
@using Assignment3.Models
@model TblMatHang


    <form id="frm" asp-controller="Home" asp-action="Index" method="post">
        Product Code: <select name="maHang" onchange="onChange()">
            @foreach (var item in ViewBag.MatHangs)
            {
                @if (ViewBag.SelectedID == item.MaHang)
                {
                    <option value="@item.MaHang" selected>@item.MaHang</option>
                }
                else
                {
                    <option value="@item.MaHang">@item.MaHang</option>
                }
            }
        </select>
    </form>


    Product name
    <form asp-controller="Home" asp-action="FilterName" method="post">
        <input type="text" name="Fname" asp-for="Tenhang" />
        <button type="submit">Filter by Name</button>
    </form>

    Unit
    <input type="text" asp-for="Dvt" />
    <br />

    <form asp-controller="Home" asp-action="FilterPrice" method="post">
        Old Price
        <input type="number" name="oldP" asp-for="Gia" /> --> New
        <input type="number" name="newP" />
        <button type="submit">Filter by Price</button>
    </form>

    Image link
    <form asp-controller="Home" asp-action="FilterImage" method="post">
        <input type="text" asp-for="Image" name="Image" />
        <button type="submit">Filter by Image</button>
    </form>

<table>
    <tr>
        <td>
            <form asp-controller="Home" asp-action="Update" method="post">
                <button type="submit">UPDATE</button>
            </form>
        </td>
        <td>
            <form asp-controller="Home" asp-action="Index">
                <button type="submit">RESET</button>
            </form>
        </td>
    </tr>
</table>

<script>
    function onChange() {
        document.getElementById("frm").submit();
    }
</script>
<br />
Danh sach mat hang:

<form id="frm" asp-controller="Home" asp-action="Index" method="post">
    <table border="1">
        <tr>
            <th>Ma Hang</td>
            <th>Ten Hang</th>
            <th>DVT</th>
            <th>Gia</th>
            <th>Image</th>
        </tr>

        @foreach (var item in ViewBag.MatHangs)
        {
            <tr>
                <td>@item.MaHang</td>
                <td>@item.Tenhang</td>
                <td>@item.Dvt</td>
                <td>@item.Gia</td>
                <td>@item.Image</td>
            </tr>
        }
    </table>
</form>

HomeController代码

using Assignment3.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;

namespace Assignment3.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                var list = context.TblMatHangs.ToList();
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                return View();
            }            
        }

        [HttpPost]
        public IActionResult Index(string maHang)
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                ViewBag.SelectedID = maHang;
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                TblMatHang m = context.TblMatHangs
                    .SingleOrDefault(x => x.MaHang == maHang);
                return View(m);
            }
        }

        [HttpPost]
        public IActionResult FilterName(string fname)
        {
            string search = fname;
            using (MyOrderContext context = new MyOrderContext())
            {
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                TblMatHang m = context.TblMatHangs
                    .FirstOrDefault(x => x.Tenhang.ToLower().Contains(search));
                ViewBag.MatHangs = context.TblMatHangs
                    .Where(x => x.Tenhang.ToLower().Contains(search)).ToList();
                return View("Index", m);
            }
        }

        public IActionResult FilterPrice(float oldP, float newP)
        {
            float oldPrice = oldP;
            float newPrice = newP;
            using (MyOrderContext context = new MyOrderContext())
            {
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                TblMatHang m = context.TblMatHangs
                    .FirstOrDefault(x => x.Gia > oldPrice && x.Gia < newPrice);
                ViewBag.MatHangs = context.TblMatHangs
                    .Where(x => x.Gia > oldPrice && x.Gia < newPrice).OrderBy(x => x.Gia).ToList();
                return View("Index", m);
            }
        }

        [HttpPost]
        public IActionResult Update(TblMatHang m)
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                m = new TblMatHang
                {

                };
                return View(m);
            }
        }

        [HttpPost]
        public IActionResult FilterImage(string image)
        {
            string search = image;
            using (MyOrderContext context = new MyOrderContext())
            {
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                TblMatHang m = context.TblMatHangs
                    .FirstOrDefault(x => x.Image.ToLower().Contains(search));
                ViewBag.MatHangs = context.TblMatHangs
                    .Where(x => x.Image.ToLower().Contains(search)).ToList();
                return View("Index", m);
            }
        }
    }
}

解决方案

核心问题分析

  1. Update表单仅含提交按钮,未包含任何模型字段,无法传递修改后的数据
  2. 多个分散表单导致模型数据无法统一收集
  3. Update方法内错误重置了传入的模型对象,未执行实际的数据库更新操作

1. 重构Index视图的Update表单

将需要更新的字段和商品标识(隐藏字段)整合到同一个Update表单中,确保提交时传递完整模型数据:

@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
@using Assignment3.Models
@model TblMatHang

<!-- 商品选择下拉框 -->
<form id="frm-select" asp-controller="Home" asp-action="Index" method="post">
    Product Code: 
    <select name="maHang" onchange="onChange()">
        @foreach (var item in ViewBag.MatHangs)
        {
            <option value="@item.MaHang" @(ViewBag.SelectedID == item.MaHang ? "selected" : "")>@item.MaHang</option>
        }
    </select>
</form>

<!-- 统一更新表单 -->
<form asp-controller="Home" asp-action="Update" method="post">
    <!-- 隐藏字段传递商品编码,用于定位数据库记录 -->
    <input type="hidden" asp-for="MaHang" />
    
    Product name: <input type="text" asp-for="Tenhang" />
    <br/>
    Unit: <input type="text" asp-for="Dvt" />
    <br/>
    Price: <input type="number" asp-for="Gia" />
    <br/>
    Image link: <input type="text" asp-for="Image" />
    <br/>
    
    <button type="submit">UPDATE</button>
    <button type="submit" formaction="@Url.Action("Index")" formmethod="get">RESET</button>
</form>

<!-- 筛选功能保留,优化表单结构 -->
<form asp-controller="Home" asp-action="FilterName" method="post">
    Filter by Name: <input type="text" name="Fname" />
    <button type="submit">Filter</button>
</form>

<form asp-controller="Home" asp-action="FilterPrice" method="post">
    Filter by Price: 
    <input type="number" name="oldP" /> --> 
    <input type="number" name="newP" />
    <button type="submit">Filter</button>
</form>

<form asp-controller="Home" asp-action="FilterImage" method="post">
    Filter by Image: <input type="text" name="Image" />
    <button type="submit">Filter</button>
</form>

<br/>
Danh sach mat hang:
<table border="1">
    <tr>
        <th>Ma Hang</th>
        <th>Ten Hang</th>
        <th>DVT</th>
        <th>Gia</th>
        <th>Image</th>
    </tr>
    @foreach (var item in ViewBag.MatHangs)
    {
        <tr>
            <td>@item.MaHang</td>
            <td>@item.Tenhang</td>
            <td>@item.Dvt</td>
            <td>@item.Gia</td>
            <td>@item.Image</td>
        </tr>
    }
</table>

<script>
    function onChange() {
        document.getElementById("frm-select").submit();
    }
</script>

2. 修改HomeController的Update方法

实现实际的数据库更新逻辑,保存后返回最新的商品列表:

using Assignment3.Models;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace Assignment3.Controllers
{
    public class HomeController : Controller
    {
        // 保留原有方法,仅修改Update方法
        [HttpPost]
        public IActionResult Update(TblMatHang updatedMatHang)
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                // 根据商品编码获取数据库中的原有记录
                var existingItem = context.TblMatHangs
                    .SingleOrDefault(x => x.MaHang == updatedMatHang.MaHang);
                
                if (existingItem != null)
                {
                    // 更新属性值
                    existingItem.Tenhang = updatedMatHang.Tenhang;
                    existingItem.Dvt = updatedMatHang.Dvt;
                    existingItem.Gia = updatedMatHang.Gia;
                    existingItem.Image = updatedMatHang.Image;
                    
                    // 保存到数据库
                    context.SaveChanges();
                }
                
                // 更新商品列表,确保视图展示最新数据
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                return View("Index", updatedMatHang);
            }
        }

        // 补充FilterPrice方法的HttpPost特性(原代码遗漏)
        [HttpPost]
        public IActionResult FilterPrice(float oldP, float newP)
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                var filteredList = context.TblMatHangs
                    .Where(x => x.Gia > oldP && x.Gia < newP).OrderBy(x => x.Gia).ToList();
                ViewBag.MatHangs = filteredList;
                var model = filteredList.FirstOrDefault();
                return View("Index", model);
            }
        }

        // 其他原有方法保持不变...
        public IActionResult Index()
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                return View();
            }            
        }

        [HttpPost]
        public IActionResult Index(string maHang)
        {
            using (MyOrderContext context = new MyOrderContext())
            {
                ViewBag.SelectedID = maHang;
                ViewBag.MatHangs = context.TblMatHangs.ToList();
                TblMatHang m = context.TblMatHangs
                    .SingleOrDefault(x => x.MaHang == maHang);
                return View(m);
            }
        }

        [HttpPost]
        public IActionResult FilterName(string fname)
        {
            string search = fname?.ToLower() ?? string.Empty;
            using (MyOrderContext context = new MyOrderContext())
            {
                var filteredList = context.TblMatHangs
                    .Where(x => x.Tenhang.ToLower().Contains(search)).ToList();
                ViewBag.MatHangs = filteredList;
                var model = filteredList.FirstOrDefault();
                return View("Index", model);
            }
        }

        [HttpPost]
        public IActionResult FilterImage(string image)
        {
            string search = image?.ToLower() ?? string.Empty;
            using (MyOrderContext context = new MyOrderContext())
            {
                var filteredList = context.TblMatHangs
                    .Where(x => x.Image.ToLower().Contains(search)).ToList();
                ViewBag.MatHangs = filteredList;
                var model = filteredList.FirstOrDefault();
                return View("Index", model);
            }
        }
    }
}

3. 额外优化点

  • 移除重复的id="frm"表单,避免DOM元素ID冲突
  • 给FilterPrice方法补充[HttpPost]特性,修复无法接收POST请求的问题
  • 优化筛选方法的空值处理,避免空引用异常
  • 将RESET按钮整合到Update表单中,减少独立表单数量

内容的提问来源于stack exchange,提问作者Harry Vo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:06:31