Considering the following data model:
public partial class RootEntity
{
[Key]
public long Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
public string ThingsAboutIt { get; set; }
public long? RelatedEntity_Id { get; set; }
[ForeignKey("RelatedEntity_Id")]
public RelatedEntity RelatedEntity { get; set; }
}
public partial class RelatedEntity
{
[Key]
public long Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
public ICollection<RootEntity> RootEntities { get; set; }
}
public partial class MyContext : IdentityDbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options) { }
public virtual DbSet<RootEntity> RootEntities { get; set; }
public virtual DbSet<RelatedEntity> RelatedEntities { get; set; }
}
When using the EF (Core) scaffolded Insert page in a Razor page application, the default pattern used for selecting singl-y linked entity records is:
<div class="form-group">
<label asp-for="RootEntity.RelatedEntity_Id" class="control-label"></label>
<select asp-for="RootEntity.RelatedEntity_Id" class ="form-control" asp-items="ViewBag.RelatedEntity_Id"></select>
</div>
and the initialization of this looks something like this:
ViewData["RelatedEntity_Id"] = new SelectList(_context.RelatedEntities, "Id", "Name");
I can configure this a tiny bit, by changing that third parameter to something like "Name" - if such a property exists.
I need way more configurabililty - I need at least null values to be selected.
In an attempt to allow nulls, I use this pattern:
List<SelectListItem> selectList = _context.RelatedEntities
.AsNoTracking()
.Select(x => new SelectListItem()
{
Value = x.Id.ToString(),
Text = x.Name
})
.ToList();
selectList.Insert(0, new SelectListItem()
{
Value = null, // <=========== Here lies the problem...
Text = "--- Select Related Entity ---"
});
ViewData["RelatedEntity_Id"] = selectList;
The rendered HTML looks something like this:
<select class="form-control" id="RootEntity_RelatedEntity_Id" name="RootEntity.RelatedEntity_Id">
<option selected="selected">--- select Related Entity ---</option>
<option value="3">FOO</option>
<option value="2">MMMBAR</option>
</select>
The problem I'm having is that the value "--- Select Related Entity ---" becomes bound to that model property. This makes it fail validation. (ModelState.IsValid == false)
I have tried changing the SelectListItem value to a blank string, "-1", but none of it fixes the model validation error.
I've also tried to build a custom binder for entity classes, but this binds the root model itself to it - which obviously does not pertain to this Select List scenario.
What is the simplest, most elegant way to resolve this?


