Vấn đề
Trong ứng dụng ASP.NET Core MVC của mình có 1 page chứa 1 form mà sau khi submit cần modify data, sau đó hiển thị lại data.
Trước khi giải quyết
Code
public class HomeController : Controller
{ [HttpGet] public IActionResult Index() { var model = new IndexViewModel { Name = "Nam" }; return View(model); } [HttpPost] public IActionResult Index(IndexViewModel model) { model.Name += " - Updated"; return View(model); }
}
View
@model IndexViewModel
@using (Html.BeginForm())
{ <input type="text" asp-for="Name" /> <span>@Model?.Name</span> <button type="submit">Submit</button>
}
Với code trên thì, Html trước khi submit
<form action="/" method="post"> <input type="text" id="Name" name="Name" value="Nam"> <span>Nam</span> <button type="submit">Submit</button>
</form>
Như chúng ta thấy thì html không có vấn đề gì, cả input value và span text đều render như ý định.
Tuy nhiên kết quả sẽ như thế nào sau khi submit? input value và span text là Nam - Updated
ư?
Không. Đây là html sau khi post.
<form action="/" method="post"> <input type="text" id="Name" name="Name" value="Nam"> <span>Nam - Updated</span> <button type="submit">Submit</button>
</form>
span text thì như ý định, còn text value thì như trước post.
Cách giải quyết
Cách 1: Dùng ModelState.Clear()
Code
public class HomeController : Controller
{ [HttpGet] public IActionResult Index() { var model = new IndexViewModel { Name = "Nam" }; return View(model); } [HttpPost] public IActionResult Index(IndexViewModel model) { ModelState.Clear(); // <-- Add here model.Name += " - Updated"; return View(model); }
}
Cách 2: Dùng ModelState.Remove();
public class HomeController : Controller
{ [HttpGet] public IActionResult Index() { var model = new IndexViewModel { Name = "Nam" }; return View(model); } [HttpPost] public IActionResult Index(IndexViewModel model) { ModelState.Remove(nameof(model.Name)); // <-- Add here model.Name += " - Updated"; return View(model); }
}
Kết quả. Trước khi submit (không có gì thay đổi). Sau khi submit , cả input value và span text đều render như mong đợi.
<form action="/" method="post"> <input type="text" id="Name" name="Name" value="Nam - Updated"> <span>Nam - Updated</span> <button type="submit">Submit</button></form>
Giải thích
Khi post thì đầu tiên data sẽ được nạp vào ModelState. Khi dùng TagHelper asp-for cho input thì đầu tiên framework sẽ tìm key ở trong ModelState. Nếu thấy thì sẽ dùng value được lưu trong ModelState. Còn nếu không thấy thì mới dùng value ở trong model. Ở ví dụ trên, khi post thì giá trị của Name được lưu trong ModelState luôn là giá trị mà ta đã submit nên value của input luôn là giá trị mà ta đã submit. Sau khi xóa toàn state của ModelState thì input value sẽ được lấy từ model.
Nguồn tham khảo: https://www.sukerou.com/2021/05/aspnet-mvchidden.html