Add FormValidationService and EventDefinitionService to dependency injection
Enhanced the application's service layer by adding FormValidationService and EventDefinitionService to the dependency injection container in Program.cs. Updated Create, Edit, and other relevant components to utilize these services for improved form validation and event processing functionality.
This commit is contained in:
@@ -3,10 +3,16 @@
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using WebApp.Components.Shared.Components
|
||||
@using Core.Utility
|
||||
@using MudBlazor
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using WebApp.Services
|
||||
@inject AppDbContext context
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ISnackbar Snackbar
|
||||
@inject FormValidationService ValidationService
|
||||
@inject EventDefinitionService EventDefinitionService
|
||||
|
||||
@if (EventDefinition is null)
|
||||
@if (EventDefinition is null || _editContext is null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
return;
|
||||
@@ -18,10 +24,12 @@
|
||||
ShowBackButton="true"
|
||||
BackButtonUrl="@(ReturnUrl ?? "/events")" />
|
||||
|
||||
<EditForm Model="EventDefinition" OnValidSubmit="OnValidSubmit" Enhance>
|
||||
<EditForm EditContext="@_editContext" OnValidSubmit="OnValidSubmit" OnInvalidSubmit="OnInvalidSubmit" Enhance>
|
||||
<FormChangeTracker @ref="_formChangeTracker" />
|
||||
<AntiforgeryToken />
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
<ValidationErrorDisplay Errors="_validationErrors" />
|
||||
|
||||
<MudStack Spacing="4">
|
||||
<MudPaper Elevation="2" Class="pa-6">
|
||||
@@ -120,6 +128,8 @@
|
||||
private EventDefinition? EventDefinition { get; set; }
|
||||
|
||||
private FormChangeTracker? _formChangeTracker;
|
||||
private EditContext? _editContext;
|
||||
private List<string> _validationErrors = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
@@ -135,96 +145,74 @@
|
||||
{
|
||||
// Populate RelatedCareersText from RelatedCareers collection
|
||||
EventDefinition.RelatedCareersText = string.Join("\n", EventDefinition.RelatedCareers.Select(c => c.Name));
|
||||
|
||||
// Create EditContext for validation
|
||||
_editContext = new EditContext(EventDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInvalidSubmit(EditContext editContext)
|
||||
{
|
||||
_validationErrors = ValidationService.HandleInvalidSubmit(editContext, EventDefinition!, errors => _validationErrors = errors);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
// To protect from overposting attacks, enable the specific properties you want to bind to.
|
||||
// For more information, see https://learn.microsoft.com/aspnet/core/blazor/forms/#mitigate-overposting-attacks.
|
||||
private async Task OnValidSubmit()
|
||||
{
|
||||
// Get the tracked entity from the database
|
||||
var trackedEntity = await context.Events
|
||||
.Include(e => e.RelatedCareers)
|
||||
.FirstOrDefaultAsync(e => e.Id == EventDefinition!.Id);
|
||||
|
||||
if (trackedEntity == null)
|
||||
{
|
||||
NavigationManager.NavigateTo("notfound");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update scalar properties from the form-bound entity
|
||||
context.Entry(trackedEntity).CurrentValues.SetValues(EventDefinition!);
|
||||
|
||||
// Normalize and process related careers
|
||||
await ProcessRelatedCareersAsync(trackedEntity);
|
||||
|
||||
try
|
||||
{
|
||||
// Get the tracked entity from the database
|
||||
var trackedEntity = await context.Events
|
||||
.Include(e => e.RelatedCareers)
|
||||
.FirstOrDefaultAsync(e => e.Id == EventDefinition!.Id);
|
||||
|
||||
if (trackedEntity == null)
|
||||
{
|
||||
Snackbar.Add("Event not found. It may have been deleted.", Severity.Error);
|
||||
NavigationManager.NavigateTo("notfound");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update scalar properties from the form-bound entity
|
||||
context.Entry(trackedEntity).CurrentValues.SetValues(EventDefinition!);
|
||||
|
||||
// Normalize and process related careers
|
||||
await EventDefinitionService.ProcessRelatedCareersAsync(trackedEntity);
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
_validationErrors.Clear();
|
||||
Snackbar.Add($"Event '{EventDefinition!.Name}' saved successfully.", Severity.Success);
|
||||
_formChangeTracker?.AllowNavigation();
|
||||
NavigationManager.NavigateTo(ReturnUrl ?? "/events");
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
catch (DbUpdateConcurrencyException ex)
|
||||
{
|
||||
if (!EventDefinitionExists(EventDefinition!.Id))
|
||||
{
|
||||
NavigationManager.NavigateTo("notfound");
|
||||
}
|
||||
else
|
||||
if (!ValidationService.HandleDbUpdateConcurrencyException(
|
||||
ex,
|
||||
() => EventDefinitionExists(EventDefinition!.Id),
|
||||
"event",
|
||||
() => NavigationManager.NavigateTo("notfound")))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (DbUpdateException ex)
|
||||
{
|
||||
ValidationService.HandleDbUpdateException(
|
||||
ex,
|
||||
"An error occurred while saving the event.",
|
||||
"event",
|
||||
"saving",
|
||||
"name");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ValidationService.HandleException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessRelatedCareersAsync(EventDefinition eventDefinition)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(eventDefinition.RelatedCareersText))
|
||||
{
|
||||
eventDefinition.RelatedCareers.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedNames = CareerNormalizer.NormalizeCareerNames(eventDefinition.RelatedCareersText).ToList();
|
||||
|
||||
if (!normalizedNames.Any())
|
||||
{
|
||||
eventDefinition.RelatedCareers.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all existing careers from database (case-insensitive lookup)
|
||||
var existingCareers = await context.Careers.ToListAsync();
|
||||
var careerLookup = existingCareers.ToDictionary(
|
||||
c => CareerNormalizer.GetNormalizedKey(c.Name),
|
||||
c => c,
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var careersToAdd = new List<Career>();
|
||||
|
||||
foreach (var normalizedName in normalizedNames)
|
||||
{
|
||||
var normalizedKey = CareerNormalizer.GetNormalizedKey(normalizedName);
|
||||
|
||||
if (careerLookup.TryGetValue(normalizedKey, out var existingCareer))
|
||||
{
|
||||
// Use existing career (preserve original capitalization)
|
||||
careersToAdd.Add(existingCareer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create new career with the normalized name (preserving capitalization from input)
|
||||
var newCareer = new Career { Name = normalizedName };
|
||||
context.Careers.Add(newCareer);
|
||||
careersToAdd.Add(newCareer);
|
||||
careerLookup[normalizedKey] = newCareer;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the collection
|
||||
eventDefinition.RelatedCareers = careersToAdd;
|
||||
}
|
||||
|
||||
private async Task HandleCancel()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user