'asp.net Core - ModelState.IsValid is requiring fields from other tables even though they are not required in the DB
When I attempt to create a "TblCompanyInfo" record I am getting an error that "The TblOutdialSetting field is required.". I assume it has to do with the foreign key that exists on TblCompanyInfo. However, this key should only require a matching CompanyID from TblCompanyInfo when you create a new record in TblOutdialSettings. I am not trying to create a new record for TblOutdialSettings, only TblCompanyInfo.
Here is my controller
// GET: Company/Create
public IActionResult Create()
{
TblCompanyInfo tblcompanyinfo = new TblCompanyInfo();
return View(tblcompanyinfo);
}
// POST: Company/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("CompanyId,Username,Password,CompanyName,ContactFirstName,ContactLastName,ContactPriPhone,ContactPriPhoneExt,ContactSecPhone,ContactSecPhoneExt,ContactEmail,Address1,Address2,City,State,Zipcode,CompanyPhone,LogoFile,Htmlcolor,CompanyUrl,CompanyEmail,AgreeToTou,AuthNetcustomerProfileId,AuthNetcustomerPaymentProfileId,PaymentInfoValid,DateTimeSignedUp,Active,TestMode,BizAcctFreeRemCount,AcctTypeId,InTrial,CompanyStatusId,OnHold,OnHoldReasonId,OnHoldStartDate")] TblCompanyInfo tblcompanyinfo)
{
if (ModelState.IsValid)
{
_context.Add(tblcompanyinfo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
else
{
foreach (var error in ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors))
{
ModelState.AddModelError(string.Empty, error.ErrorMessage);
}
}
return View(tblcompanyinfo);
}
Here is my View
@model AppointmentRemindersNetCoreMVC.Models.TblCompanyInfo
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
@*@Html.ValidationSummary(true)*@
<h4>TblCompanyInfo</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Username" class="control-label"></label>
<input asp-for="Username" class="form-control" />
<span asp-validation-for="Username" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CompanyName" class="control-label"></label>
<input asp-for="CompanyName" class="form-control" />
<span asp-validation-for="CompanyName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactFirstName" class="control-label"></label>
<input asp-for="ContactFirstName" class="form-control" />
<span asp-validation-for="ContactFirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactLastName" class="control-label"></label>
<input asp-for="ContactLastName" class="form-control" />
<span asp-validation-for="ContactLastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactPriPhone" class="control-label"></label>
<input asp-for="ContactPriPhone" class="form-control" />
<span asp-validation-for="ContactPriPhone" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactPriPhoneExt" class="control-label"></label>
<input asp-for="ContactPriPhoneExt" class="form-control" />
<span asp-validation-for="ContactPriPhoneExt" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactSecPhone" class="control-label"></label>
<input asp-for="ContactSecPhone" class="form-control" />
<span asp-validation-for="ContactSecPhone" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactSecPhoneExt" class="control-label"></label>
<input asp-for="ContactSecPhoneExt" class="form-control" />
<span asp-validation-for="ContactSecPhoneExt" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactEmail" class="control-label"></label>
<input asp-for="ContactEmail" class="form-control" />
<span asp-validation-for="ContactEmail" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address1" class="control-label"></label>
<input asp-for="Address1" class="form-control" />
<span asp-validation-for="Address1" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address2" class="control-label"></label>
<input asp-for="Address2" class="form-control" />
<span asp-validation-for="Address2" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="City" class="control-label"></label>
<input asp-for="City" class="form-control" />
<span asp-validation-for="City" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="State" class="control-label"></label>
<input asp-for="State" class="form-control" />
<span asp-validation-for="State" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Zipcode" class="control-label"></label>
<input asp-for="Zipcode" class="form-control" />
<span asp-validation-for="Zipcode" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CompanyPhone" class="control-label"></label>
<input asp-for="CompanyPhone" class="form-control" />
<span asp-validation-for="CompanyPhone" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="AgreeToTou" /> @Html.DisplayNameFor(model => model.AgreeToTou)
</label>
</div>
@
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Here is my TblCompanyInfo.cs class
using System;
using System.Collections.Generic;
namespace AppointmentRemindersNetCoreMVC.Models
{
public partial class TblCompanyInfo
{
public TblCompanyInfo()
{
TblCalendarData = new HashSet<TblCalendarDatum>();
TblClientVoicefiles = new HashSet<TblClientVoicefile>();
TblCompanyToBillingItems = new HashSet<TblCompanyToBillingItem>();
TblEnglishSpanishMappings = new HashSet<TblEnglishSpanishMapping>();
TblEvents = new HashSet<TblEvent>();
TblImportData = new HashSet<TblImportDatum>();
TblImportLogs = new HashSet<TblImportLog>();
TblNoReminderLists = new HashSet<TblNoReminderList>();
TblReportData = new HashSet<TblReportDatum>();
TblResellerPaymentCustomerCompanies = new HashSet<TblResellerPayment>();
TblResellerPaymentResellerCompanies = new HashSet<TblResellerPayment>();
TblResellerToCompanyCompanies = new HashSet<TblResellerToCompany>();
TblResellerToCompanySalesCompanies = new HashSet<TblResellerToCompany>();
TblRules = new HashSet<TblRule>();
}
public long CompanyId { get; set; }
public string Username { get; set; } = null!;
public string Password { get; set; } = null!;
public string CompanyName { get; set; } = null!;
public string ContactFirstName { get; set; } = null!;
public string ContactLastName { get; set; } = null!;
public string ContactPriPhone { get; set; } = null!;
public string? ContactPriPhoneExt { get; set; }
public string? ContactSecPhone { get; set; }
public string? ContactSecPhoneExt { get; set; }
public string? ContactEmail { get; set; }
public string? Address1 { get; set; }
public string? Address2 { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public string? Zipcode { get; set; }
public string? CompanyPhone { get; set; }
public string? LogoFile { get; set; }
public string? Htmlcolor { get; set; }
public string? CompanyUrl { get; set; }
public string? CompanyEmail { get; set; }
public bool AgreeToTou { get; set; }
public string? AuthNetcustomerProfileId { get; set; }
public string? AuthNetcustomerPaymentProfileId { get; set; }
public bool PaymentInfoValid { get; set; }
public DateTime DateTimeSignedUp { get; set; }
public bool? Active { get; set; }
public bool TestMode { get; set; }
public int BizAcctFreeRemCount { get; set; }
public int AcctTypeId { get; set; }
public bool? InTrial { get; set; }
public int CompanyStatusId { get; set; }
public bool OnHold { get; set; }
public int OnHoldReasonId { get; set; }
public DateTime OnHoldStartDate { get; set; }
public virtual TblAcctType? AcctType { get; set; } = null!;
public virtual TblCompanyStatusId? CompanyStatus { get; set; } = null!;
public virtual TblOnHoldReason? OnHoldReason { get; set; } = null!;
public virtual TblBillingTypeToCompany? TblBillingTypeToCompany { get; set; } = null!;
public virtual TblOutdialSetting? TblOutdialSetting { get; set; } = null!;
public virtual ICollection<TblCalendarDatum> TblCalendarData { get; set; }
public virtual ICollection<TblClientVoicefile> TblClientVoicefiles { get; set; }
public virtual ICollection<TblCompanyToBillingItem> TblCompanyToBillingItems { get; set; }
public virtual ICollection<TblEnglishSpanishMapping> TblEnglishSpanishMappings { get; set; }
public virtual ICollection<TblEvent> TblEvents { get; set; }
public virtual ICollection<TblImportDatum> TblImportData { get; set; }
public virtual ICollection<TblImportLog> TblImportLogs { get; set; }
public virtual ICollection<TblNoReminderList> TblNoReminderLists { get; set; }
public virtual ICollection<TblReportDatum> TblReportData { get; set; }
public virtual ICollection<TblResellerPayment> TblResellerPaymentCustomerCompanies { get; set; }
public virtual ICollection<TblResellerPayment> TblResellerPaymentResellerCompanies { get; set; }
public virtual ICollection<TblResellerToCompany> TblResellerToCompanyCompanies { get; set; }
public virtual ICollection<TblResellerToCompany> TblResellerToCompanySalesCompanies { get; set; }
public virtual ICollection<TblRule> TblRules { get; set; }
}
}
Solution 1:[1]
you are probably using Net 6. You can remove option nullable from project configuration
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
or make nullable your problem properties. But in this case you will probably have to do this to most properties in your another classes too
public TblOutdialSetting? TblOutdialSetting {get; set;}
and fix create code. Try to use this syntax. Ef sometimes can't figure what table to update if you don't put it explicitly.
_context.Set<TblCompanyInfo>().Add(tblcompanyinfo);
await _context.SaveChangesAsync();
and IMHO you have to remove [Bind] from the action. I don' t see any sense in using this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

