I’m trying to understand how model validation works as I finalize the design on my website using asp.net mvc in Visual Studio, framework .NET 8.0. I’ve read several tutorials and posts on here, but the behavior I’m seeing doesn’t seem to match what I was expecting.
using System.ComponentModel.DataAnnotations;
namespace mywebsite.Models
{
public class TestAModel
{
//[Required]
//public int nonnullableint { get; set; }
//public int? nullableint { get; set; }
//public string? nullablestring { get; set; }
//public string nonnullablestring { get; set; }
//public TestCModel? nullablenonrequiredmodel { get; set; }
public TestCModel nonnullablenonrequiredmodel { get; set; }
//public TestBModel? nullablerequiredmodel { get; set; }
//public TestBModel nonnullablerequiredmodel { get; set; }
//public List<TestBModel>? nullablerequiredmodellist { get; set; }
//public List<TestBModel> nonnullablerequiredmodellist { get; set; }
//public List<TestCModel>? nullablenonrequiredmodellist { get; set; }
//public List<TestCModel> nonnullablenonrequiredmodellist { get; set; }
}
}
namespace mywebsite.Models
{
public class TestCModel
{
public int? notrequiredint { get; set; }
}
}
HomeController’s Index() action
public IActionResult Index()
{
TestAModel model = new TestAModel();
//model.nonnullablenonrequiredmodel = new TestCModel();
var validate = TryValidateModel(model);
if(ModelState.IsValid){
var variabletest = 1;
}
return View(); //breakpoint here to view results
}
What I’ve found, using TestCModel as an example is basically this:
public class TestAModel
{
//[Required]
public TestCModel? nonnullablenonrequiredmodel { get; set; }
}
public IActionResult Index()
{
TestAModel model = new TestAModel();
//model.nonnullablenonrequiredmodel = new TestCModel();
var validate = TryValidateModel(model);
if(ModelState.IsValid){
var variabletest = 1;
}
return View();
}
validation = true
public class TestAModel
{
[Required]
public TestCModel? nonnullablenonrequiredmodel { get; set; }
}
public IActionResult Index()
{
TestAModel model = new TestAModel();
//model.nonnullablenonrequiredmodel = new TestCModel();
var validate = TryValidateModel(model);
if(ModelState.IsValid){
var variabletest = 1;
}
return View();
}
validation = false
public class TestAModel
{
[Required]
public TestCModel? nonnullablenonrequiredmodel { get; set; }
}
public IActionResult Index()
{
TestAModel model = new TestAModel();
model.nonnullablenonrequiredmodel = new TestCModel();
var validate = TryValidateModel(model);
if(ModelState.IsValid){
var variabletest = 1;
}
return View();
}
validation = true
All of which makes sense to me, except then when I did this:
public class TestAModel
{
//[Required]
public TestCModel nonnullablenonrequiredmodel { get; set; }
}
public IActionResult Index()
{
TestAModel model = new TestAModel();
//model.nonnullablenonrequiredmodel = new TestCModel();
var validate = TryValidateModel(model);
if(ModelState.IsValid){
var variabletest = 1;
}
return View();
}
validation = false!
I don’t understand this because aren’t classes inherently nullable? I also don’t understand this, because it seems to limit the value of the [Required] tag. What’s the point of it if something is required simply by leaving it non-nullable? I had the same results with string types as well.
The only thing interesting was int types, because the non-nullable int defaulted to a value = 0, so the way to make it required was [Required] and nullable.
Am I missing something super basic? please help.