My ASP.NET Core (or MVC .NET Framework) form is showing unexpected behavior: the data I enter in the fields does not reach my controller correctly, resulting in null properties in my model. I have already checked the 'Network' tab of the browser, and in the POST request I can clearly see the values filled in the 'Payload'/'Request Body'.
Some things I have already tried/checked:
The names of the inputs in the HTML (asp-for/name) exactly match the names of the properties in my model.
The action in my controller is decorated with [HttpPost].
Even with these checks, the values continue to arrive null on the server. Is there any other possible cause for this problem that I can investigate?
ResisterCategory.cshtml:
@model CategoryModel
@{
Layout = "_Layout";
}
<div class="text-center">
<h1 class="display-4">Cadastrar Categoria</h1>
<form class="form-control" asp-controller="ControlPanel" asp-action="RegisterCategory" method="post">
<div class="mb-3">
<label for="category" class="form-label">Categoria</label>
<input type="text" asp-for="Category" class="form-control" id="category" placeholder="Ex: Camisa">
</div>
<div class="btn-group" role="group">
<a role="button" class="btn btn-outline-danger" asp-controller="ControlPanel" asp-action="Category">Voltar</a>
<button type="submit" class="btn btn-primary text-end">Adicionar</button>
</div>
</form>
</div>
ControlPanelController.cs:
public class ControlPanelController : Controller {
private readonly ICategoryRepository _categoryRepository;
private readonly ISizeRepository _sizeRepository;
private readonly IColorRepository _colorRepository;
private readonly ILogger<ControlPanelController> _logger;
public ControlPanelController(
ICategoryRepository categoryRepository, ISizeRepository sizeRepository, IColorRepository colorRepository,
ILogger<ControlPanelController> logger
) {
_categoryRepository = categoryRepository;
_sizeRepository = sizeRepository;
_colorRepository = colorRepository;
_logger = logger;
}
// GET
public IActionResult Category() {
// lists the categories and has a button that sends to RegisterCategory, UpdateCategory, DeleteCategory
List<CategoryModel> categories = _categoryRepository.FindAll();
return View(categories);
}
public IActionResult RegisterCategory() { // form to register a new category
return View();
}
// POST
[HttpPost]
public IActionResult EditCategory(CategoryModel category) {
_categoryRepository.Update(category);
return RedirectToAction("Category");
}
[HttpPost]
public IActionResult RegisterCategory(CategoryModel category) {
_categoryRepository.Create(category);
return RedirectToAction("Category");
}
CategoryRepository.cs:
public class CategoryRepository : ICategoryRepository {
private readonly BankContext _context;
public CategoryRepository(BankContext context) {
_context = context;
}
// FIND
public List<CategoryModel> FindAll() {
return _context.Categories.ToList();
}
public CategoryModel FindById(int id) {
return _context.Categories.FirstOrDefault(x => x.CategoryId == id);
}
// UPDATE
public CategoryModel Update(CategoryModel category) {
CategoryModel categoryDb = FindById(category.CategoryId);
if (categoryDb == null) throw new Exception("Houve um erro ao atualizar a categoria");
categoryDb.Category = category.Category;
_context.Categories.Update(categoryDb);
_context.SaveChanges();
return categoryDb;
}
// CREATE
public CategoryModel Create(CategoryModel category) {
_context.Categories.Add(category);
_context.SaveChanges();
return category;
}
// KILL
}
CategoryModel.cs:
public class CategoryModel {
public int CategoryId { get; set; }
public string Category { get; set; } = null!;
public virtual ICollection<ProductCategoryModel> ProductCategories { get; set; } = new List<ProductCategoryModel>();
}
BankContext.cs:
public class BankContext : DbContext {
public BankContext(DbContextOptions<BankContext> options) : base(options) {
}
public DbSet<CategoryModel> Categories { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder) {
// Category
modelBuilder.Entity<CategoryModel>()
.HasKey(c => c.CategoryId);
modelBuilder.Entity<CategoryModel>().Property(c => c.CategoryId).HasColumnName("category_id")
.ValueGeneratedOnAdd();
modelBuilder.Entity<CategoryModel>().Property(c => c.Category).HasColumnName("category").IsRequired()
.HasMaxLength(100);
modelBuilder.Entity<CategoryModel>().HasMany(c => c.ProductCategories).WithOne(pc => pc.Category)
.HasForeignKey(pc => pc.CategoryId).HasConstraintName("FK_ProductCategory_Category");
}
I didn't send it, but it's not just category that sends null, size and color too, the logic is the same
I've used both asp-for and name in the form, both gave an error
I'm using dotnet9 but 8 also gave the same result