I got rid of some errors by removing the required annotations from things that are not populated via the form like UserID, but I still have the problem of category specific required fields being required no matter what category is selected. Those fields
must be required whenever a record is inserted into a category specific table, but not when a record is being added to a different category.
These are some code snippets from the relevant parts of my page:
Here is an example from the Services model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PostAlmostAnything.Models
{
public partial class Services
{
[Key]
public int Serviceid { get; set; }
[Required]
public int? Post { get; set; }
[Required(ErrorMessage = "Price Required!")]
[Range(.00, Double.PositiveInfinity, ErrorMessage = "Must Be Positive Number!")]
[Display(Name = "Price:")]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal? Price { get; set; }
[Required(ErrorMessage = "Service Rate Required!")]
[Range(1, Double.PositiveInfinity, ErrorMessage = "Service Rate Required!")]
[Display(Name = "Service Rate:")]
public int? Servicerate { get; set; }
[Required(ErrorMessage = "Currency Required!")]
[Range(1, Double.PositiveInfinity, ErrorMessage = "Currency Required!")]
[Display(Name = "Currency:")]
public int? Currency { get; set; }
[Required(ErrorMessage = "Service Hours Required!")]
[StringLength(500)]
[RegularExpression("^(?!.*<[^>]+>).*", ErrorMessage = "No HTML tags allowed!")]
[Display(Name = "Service Hours:")]
public string Hours { get; set; }
public virtual Currency CurrencyNavigation { get; set; }
public virtual Posts PostNavigation { get; set; }
public virtual Servicerate ServicerateNavigation { get; set; }
}
}
Then the form used to create a new post loads partials like this when a category is selected:
[BindProperty]
public Posts Posts
{
get;
set;
}
[BindProperty]
public Community Community
{
get;
set;
}
[BindProperty]
public Housing Housing
{
get;
set;
}
[BindProperty]
public Jobs Jobs
{
get;
set;
}
[BindProperty]
public Personals Personals
{
get;
set;
}
[BindProperty]
public Rantrave Rantrave
{
get;
set;
}
[BindProperty]
public Services Services
{
get;
set;
}
[BindProperty]
public Shopping Shopping
{
get;
set;
}
public InputModel Input
{
get;
set;
}
public IActionResult OnGet()
{
ViewData["ListofCategories"] = new SelectList(_context.Categories.Where(c => c.Site == GlobalStatic.SITENUMBER()), "Categoryid", "Categoryname");
return Page();
}
public PartialViewResult OnGetCategoryPartial(int Categoryid)
{
string partialname = String.Empty;
switch (Categoryid)
{
case 1:
partialname = "_CreateCommunity";
break;
case 2:
partialname = "_CreatePersonals";
break;
case 3:
partialname = "_CreateHousing";
break;
case 4:
partialname = "_CreateShopping";
break;
case 5:
partialname = "_CreateServices";
break;
case 6:
partialname = "_CreateJobs";
break;
case 8:
partialname = "_CreateRantrave";
break;
}
return Partial(partialname);
}
Here are the parts of the post event relevant to Posts and categories
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
// Set Parameters That Don't Require User Input
Posts.Adminban = false;
Posts.Active = true;
Posts.Dateposted = DateTime.Now;
Posts.Site = GlobalStatic.SITENUMBER();
Posts.Ipaddress = _accessor.HttpContext.Connection.RemoteIpAddress.ToString();
int? sc = Convert.ToInt32(HttpContext.Request.Form["Subcategoryid"]);
int? sc2 = Convert.ToInt32(HttpContext.Request.Form["Subcategory2id"]);
Posts.Subcategory = sc;
Posts.Subcategory2 = sc2;
if (User.Identity.IsAuthenticated)
{
IdentityUser user = await _userManager.GetUserAsync(User);
Posts.Userid = await _userManager.GetUserIdAsync(user);
}
else
{
return Page();
}
_context.Posts.Add(Posts);
if (Posts.Category != null)
{
int? catid = Posts.Category;
switch (catid)
{
case 1:
Community.Post = Posts.Postid;
_context.Community.Add(Community);
break;
case 2:
Personals.Post = Posts.Postid;
_context.Personals.Add(Personals);
break;
case 3:
Housing.Post = Posts.Postid;
_context.Housing.Add(Housing);
break;
case 4:
Shopping.Post = Posts.Postid;
_context.Shopping.Add(Shopping);
break;
case 5:
Services.Post = Posts.Postid;
_context.Services.Add(Services);
break;
case 6:
Jobs.Post = Posts.Postid;
_context.Jobs.Add(Jobs);
break;
case 8:
Rantrave.Post = Posts.Postid;
Rantrave.Nameurl = linkgenerator.rrtagurl(Rantrave.Name);
_context.Rantrave.Add(Rantrave);
break;
}
}
await _context.SaveChangesAsync();
string targeturl = linkgenerator.postlink(Posts.Postid, Posts.Title);
return RedirectToPage(targeturl);
}
So there it is. For efficiency I did not include all of the model and I limited the code for the dropdown lists to just categories because the partials loaded based on category on the ones with the required fields.
The problem seems to be that every partial is being required regardless of which one is actually loaded into the form. The solution to this is probably simple, but I am new to .Net Core and have never built a form this complex before. Even after I fix this
issue I still have to add a feature for uploading images.
UPDATE: I made some changes. I removed the BindProperty for all the category tables in my index.cshtml.cs file and I moved await _context.SaveChangesAsync(); up so that it runs before I need to grab the Postid of the new record. Now I get the following error:
Unfortunately, When I try to post to Community I get an error saying that
An unhandled exception occurred while processing the request.
<div class="titleerror">NullReferenceException: Object reference not set to an instance of an object.</div>
PostAlmostAnything.Pages.post.IndexModel.OnPostAsync() inIndex.cshtml.cs, line 177
Stack
Query
Cookies
Headers
Routing
<div id="stackpage" class="page">
NullReferenceException: Object reference not set to an instance of an object.
So, why isn't scoped identity working as described here https://www.entityframeworktutorial.net/faq/how-to-get-id-of-saved-entity-in-entity-framework.aspx
</div>
</div>
According to this
https://entityframework.net/retrieve-id-of-inserted-entity what I am doing should work because the record is created the same way right before the Postid is needed and used. I checked the database and confirmed that the new record was created and the new
record has a Postid, but Posts.Postid is null according to the page.
Member
5 Points
205 Posts
Re: Validation Firing for Required Fields Populated from Code Behind When Form is Submitted
Oct 25, 2020 02:09 AM|CopBlaster|LINK
I got rid of some errors by removing the required annotations from things that are not populated via the form like UserID, but I still have the problem of category specific required fields being required no matter what category is selected. Those fields must be required whenever a record is inserted into a category specific table, but not when a record is being added to a different category.
These are some code snippets from the relevant parts of my page:
Here is an example from the Services model
Then the form used to create a new post loads partials like this when a category is selected:
Then in the Index.cshtml.cs file I have this
Here are the parts of the post event relevant to Posts and categories
So there it is. For efficiency I did not include all of the model and I limited the code for the dropdown lists to just categories because the partials loaded based on category on the ones with the required fields.
The problem seems to be that every partial is being required regardless of which one is actually loaded into the form. The solution to this is probably simple, but I am new to .Net Core and have never built a form this complex before. Even after I fix this issue I still have to add a feature for uploading images.
UPDATE: I made some changes. I removed the BindProperty for all the category tables in my index.cshtml.cs file and I moved await _context.SaveChangesAsync(); up so that it runs before I need to grab the Postid of the new record. Now I get the following error:
Unfortunately, When I try to post to Community I get an error saying that
An unhandled exception occurred while processing the request.
<div class="titleerror">NullReferenceException: Object reference not set to an instance of an object.</div>
PostAlmostAnything.Pages.post.IndexModel.OnPostAsync() in
Index.cshtml.cs
, line 177<div id="stackpage" class="page">
NullReferenceException: Object reference not set to an instance of an object.
PostAlmostAnything.Pages.post.IndexModel.OnPostAsync() in
<button class="expandCollapseButton" data-frameid="frame1">-</button> <div class="source">Index.cshtml.cs
So, why isn't scoped identity working as described here https://www.entityframeworktutorial.net/faq/how-to-get-id-of-saved-entity-in-entity-framework.aspx
</div></div>
According to this https://entityframework.net/retrieve-id-of-inserted-entity what I am doing should work because the record is created the same way right before the Postid is needed and used. I checked the database and confirmed that the new record was created and the new record has a Postid, but Posts.Postid is null according to the page.