ASP.NET表单值传递至控制器及方法自动调用问题求助
解决ASP.NET表单提交与控制器方法触发的问题
咱们来逐个拆解你遇到的两个问题,一步步搞定它们:
问题1:访问/AddUser时自动调用AddUser方法
这是因为你当前的AddUser方法没有限定请求类型,ASP.NET默认会把GET请求也映射到这个方法。当你在浏览器输入/AddUser时,发起的是GET请求,所以方法会自动执行,触发插入逻辑。
解决方案:给控制器方法拆分出GET和POST两个版本,用特性明确限定请求类型:
using System; using System.Collections.Generic; using System.Diagnostics; using Microsoft.AspNetCore.Mvc; using nmvs_db.dal; using nmvs_module; using nmvs_module.util; using SecureMedi.Models; using SecureMedi.DAL; namespace SecureMedi.Controllers { public class HomeController : Controller { // 处理GET请求:仅返回表单页面,不执行插入逻辑 [HttpGet] public ActionResult AddUser() { return View(new Users()); // 传入空模型渲染表单 } // 处理POST请求:仅在表单提交时触发 [HttpPost] public ActionResult AddUser(Users u) { if (ModelState.IsValid) // 先验证用户输入是否合法 { UsersDAL ud = new UsersDAL(); ud.Insert(u); // 提交成功后建议重定向到其他页面(比如用户列表),避免重复提交 return RedirectToAction("Index"); } // 如果验证失败,返回表单页面并保留用户输入内容 return View(u); } } }
这样调整后,访问/AddUser只会显示表单,只有点击提交按钮发起POST请求时,才会执行数据插入逻辑。
问题2:表单值无法传递到控制器
这里有两个关键错误需要修正:
1. 视图的控制器名称写错了
你的表单标签里asp-controller="Index"是错误的——你的控制器是HomeController,所以应该改成asp-controller="Home",否则表单会提交到不存在的IndexController,自然拿不到输入值:
@model SecureMedi.Models.Users <form asp-controller="Home" asp-action="AddUser" method="post"> <div class="form-group"> <label asp-for="Username">Username</label> <input asp-for="Username" class="form-control" /> </div> <!-- / form-group --> <div class="form-group"> <!-- 这里的label文本写错了,改成Role更合理 --> <label asp-for="Role">Role</label> <input asp-for="Role" class="form-control" /> </div> <!-- / form-group --> <button type="submit" class="btn btn-primary">Add User</button> </form> <!-- / form -->
另外Role对应的label文本写成了"Username",这是笔误,虽然不影响模型绑定,但为了用户体验建议修正。
2. 确保模型绑定正常工作
修正表单的控制器指向后,ASP.NET的模型绑定会自动把表单中的Username和Role值填充到Users对象里。配合上面的[HttpPost]方法,就能正确获取用户输入的真实值了。
重要提醒:防范SQL注入风险
你的DAL层用String.Format拼接SQL语句,存在严重的SQL注入漏洞!比如用户输入的Username是'; DROP TABLE Users;--,会直接执行恶意操作。建议改用参数化查询:
public void Insert(Users u) { string connectionstring = "MY_CONNECTION_STRING"; using (SqlConnection conn = new SqlConnection(connectionstring)) { string createUserSql = "CREATE USER @Username WITHOUT LOGIN"; string addRoleSql = "ALTER ROLE @Role ADD MEMBER @Username"; SqlCommand cmd = new SqlCommand(createUserSql, conn); cmd.Parameters.AddWithValue("@Username", u.Username); SqlCommand cmd2 = new SqlCommand(addRoleSql, conn); cmd2.Parameters.AddWithValue("@Username", u.Username); cmd2.Parameters.AddWithValue("@Role", u.Role); try { conn.Open(); using (var transaction = conn.BeginTransaction()) { cmd.Transaction = transaction; cmd.ExecuteNonQuery(); cmd2.Transaction = transaction; cmd2.ExecuteNonQuery(); transaction.Commit(); } } } }
参数化查询能彻底避免SQL注入,让你的代码更安全可靠。
内容的提问来源于stack exchange,提问作者0xburned




