Fehlerbehandlung, Logging und feldbezogene Validierung (Kapitel 13.2)
Zentrale Exception-Behandlung (Dispatcher.UIThread.UnhandledException, AppDomain, TaskScheduler) verhindert Abstürze und protokolliert Fehler über AppLogger in eine rotierende Log-Datei im App-Datenverzeichnis. Toast-Benachrichtigungen zeigen Erfolg/Fehler global an. Alle Dialoge mit Formularfeldern zeigen Validierungsmeldungen jetzt direkt am betroffenen Feld statt in einem Sammel-Label. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,9 @@ public partial class ExamDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private int? _examNumber;
|
||||
[ObservableProperty] private string _notes = "";
|
||||
[ObservableProperty] private string _returnedAtText = "";
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _titleError = "";
|
||||
[ObservableProperty] private string _dateTextError = "";
|
||||
[ObservableProperty] private string _returnedAtTextError = "";
|
||||
[ObservableProperty] private double _totalPoints;
|
||||
[ObservableProperty] private bool _hasCompetencyCatalog;
|
||||
[ObservableProperty] private bool _useWeighting;
|
||||
@@ -264,27 +266,34 @@ public partial class ExamDialogViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void Save()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Title)) { ValidationMessage = "Titel erforderlich."; return; }
|
||||
if (!DateOnly.TryParseExact(DateText, "dd.MM.yyyy", null, DateTimeStyles.None, out var date))
|
||||
TitleError = ""; DateTextError = ""; ReturnedAtTextError = ""; GradingKeyValidation = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Title)) { TitleError = "Titel erforderlich."; valid = false; }
|
||||
|
||||
DateOnly date = default;
|
||||
if (!DateOnly.TryParseExact(DateText, "dd.MM.yyyy", null, DateTimeStyles.None, out date))
|
||||
{
|
||||
ValidationMessage = "Datum im Format TT.MM.JJJJ eingeben.";
|
||||
return;
|
||||
DateTextError = "Format TT.MM.JJJJ.";
|
||||
valid = false;
|
||||
}
|
||||
|
||||
DateOnly? returnedAt = null;
|
||||
if (!string.IsNullOrWhiteSpace(ReturnedAtText))
|
||||
{
|
||||
if (!DateOnly.TryParseExact(ReturnedAtText, "dd.MM.yyyy", null, DateTimeStyles.None, out var r))
|
||||
{
|
||||
ValidationMessage = "Rückgabedatum im Format TT.MM.JJJJ eingeben.";
|
||||
return;
|
||||
ReturnedAtTextError = "Format TT.MM.JJJJ.";
|
||||
valid = false;
|
||||
}
|
||||
returnedAt = r;
|
||||
else returnedAt = r;
|
||||
}
|
||||
|
||||
var gradingKey = BuildGradingKeyEntries();
|
||||
var gradingKeyError = _grading.ValidateGradingKey(gradingKey);
|
||||
if (gradingKeyError is not null) { GradingKeyValidation = gradingKeyError; return; }
|
||||
GradingKeyValidation = "";
|
||||
if (gradingKeyError is not null) { GradingKeyValidation = gradingKeyError; valid = false; }
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
Result = _editingExam ?? new Exam { GroupId = _groupId };
|
||||
Result.Title = Title.Trim();
|
||||
|
||||
@@ -315,11 +315,16 @@ public partial class StudentGradesDialogViewModel : ObservableObject
|
||||
|
||||
private void Save(GradeEditItem item)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item.Value)) { item.ValidationMessage = "Wert darf nicht leer sein."; return; }
|
||||
item.ValueError = ""; item.DateTextError = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(item.Value)) { item.ValueError = "Wert darf nicht leer sein."; valid = false; }
|
||||
if (!DateOnly.TryParseExact(item.DateText, "dd.MM.yyyy", null,
|
||||
System.Globalization.DateTimeStyles.None, out _))
|
||||
{ item.ValidationMessage = "Datum im Format TT.MM.JJJJ eingeben."; return; }
|
||||
item.ValidationMessage = "";
|
||||
{ item.DateTextError = "Format TT.MM.JJJJ."; valid = false; }
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
var grade = item.ToModel();
|
||||
_grades.Save(grade);
|
||||
item.IsNew = false;
|
||||
@@ -345,7 +350,8 @@ public partial class GradeEditItem : ObservableObject
|
||||
[ObservableProperty] private string _dateText;
|
||||
[ObservableProperty] private double _weight;
|
||||
[ObservableProperty] private string? _note;
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _valueError = "";
|
||||
[ObservableProperty] private string _dateTextError = "";
|
||||
|
||||
// Für die ComboBox: deutsche Anzeige statt des rohen Enum-Namens.
|
||||
public string CategoryName
|
||||
@@ -405,7 +411,7 @@ public partial class CollectiveGradeDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private double _weight = 1.0;
|
||||
[ObservableProperty] private string? _note;
|
||||
[ObservableProperty] private string _statusMessage = "";
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _dateTextError = "";
|
||||
|
||||
// Für die ComboBox: deutsche Anzeige statt des rohen Enum-Namens.
|
||||
public string CategoryName
|
||||
@@ -428,8 +434,8 @@ public partial class CollectiveGradeDialogViewModel : ObservableObject
|
||||
{
|
||||
if (!DateOnly.TryParseExact(DateText, "dd.MM.yyyy", null,
|
||||
System.Globalization.DateTimeStyles.None, out var date))
|
||||
{ ValidationMessage = "Datum im Format TT.MM.JJJJ eingeben."; return; }
|
||||
ValidationMessage = "";
|
||||
{ DateTextError = "Format TT.MM.JJJJ."; return; }
|
||||
DateTextError = "";
|
||||
|
||||
var count = 0;
|
||||
foreach (var row in Rows)
|
||||
|
||||
@@ -618,7 +618,8 @@ public partial class AddGroupDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private int? _hoursPerWeek;
|
||||
[ObservableProperty] private bool _isOwnClass;
|
||||
[ObservableProperty] private bool _isDifferentiated;
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _nameError = "";
|
||||
[ObservableProperty] private string _gradeLevelError = "";
|
||||
|
||||
public List<string> SchoolYears { get; }
|
||||
public List<string> GradingOptions { get; } = ["Noten 1–6", "Punkte 0–15"];
|
||||
@@ -662,8 +663,13 @@ public partial class AddGroupDialogViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void Save()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Name)) { ValidationMessage = "Bezeichnung erforderlich."; return; }
|
||||
if (GradeLevel is < 1 or > 13) { ValidationMessage = "Klassenstufe 1–13."; return; }
|
||||
NameError = ""; GradeLevelError = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Name)) { NameError = "Bezeichnung erforderlich."; valid = false; }
|
||||
if (GradeLevel is < 1 or > 13) { GradeLevelError = "Klassenstufe 1–13."; valid = false; }
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
string? subjectName = !string.IsNullOrWhiteSpace(Subject) ? Subject.Trim() : null;
|
||||
Guid? subjectId = null;
|
||||
|
||||
@@ -671,7 +671,7 @@ public partial class AddSessionDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private DateOnly _date = DateOnly.FromDateTime(DateTime.Today);
|
||||
[ObservableProperty] private string _comment = "";
|
||||
[ObservableProperty] private string _dateText = DateOnly.FromDateTime(DateTime.Today).ToString("dd.MM.yyyy");
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _dateTextError = "";
|
||||
|
||||
public ParticipationSession? Result { get; private set; }
|
||||
|
||||
@@ -681,9 +681,10 @@ public partial class AddSessionDialogViewModel : ObservableObject
|
||||
if (!DateOnly.TryParseExact(DateText, "dd.MM.yyyy", null,
|
||||
System.Globalization.DateTimeStyles.None, out var date))
|
||||
{
|
||||
ValidationMessage = "Datum im Format TT.MM.JJJJ eingeben.";
|
||||
DateTextError = "Format TT.MM.JJJJ.";
|
||||
return;
|
||||
}
|
||||
DateTextError = "";
|
||||
Result = new ParticipationSession { Date = date, Comment = Comment.Trim() };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private string _progressText = "";
|
||||
[ObservableProperty] private string _newSectionLabel = "";
|
||||
[ObservableProperty] private string _newSectionEndDateText = DateOnly.FromDateTime(DateTime.Today).ToString("dd.MM.yyyy");
|
||||
[ObservableProperty] private string _sectionValidationMessage = "";
|
||||
[ObservableProperty] private string _newSectionLabelError = "";
|
||||
[ObservableProperty] private string _newSectionEndDateTextError = "";
|
||||
[ObservableProperty] private ParticipationPeriodOption _rollupPeriod;
|
||||
[ObservableProperty] private string _rollupStatusMessage = "";
|
||||
[ObservableProperty] private double _timelineZoom = 1.0;
|
||||
@@ -322,13 +323,20 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void CloseSection()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NewSectionLabel)) { SectionValidationMessage = "Bezeichnung erforderlich."; return; }
|
||||
NewSectionLabelError = ""; NewSectionEndDateTextError = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(NewSectionLabel)) { NewSectionLabelError = "Bezeichnung erforderlich."; valid = false; }
|
||||
|
||||
DateOnly end = default;
|
||||
if (!DateOnly.TryParseExact(NewSectionEndDateText, "dd.MM.yyyy", null,
|
||||
DateTimeStyles.None, out var end))
|
||||
{ SectionValidationMessage = "Datum im Format TT.MM.JJJJ eingeben."; return; }
|
||||
DateTimeStyles.None, out end))
|
||||
{ NewSectionEndDateTextError = "Format TT.MM.JJJJ."; valid = false; }
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
var start = ComputeOpenStart();
|
||||
if (end < start) { SectionValidationMessage = "Enddatum liegt vor Abschnittsbeginn."; return; }
|
||||
if (end < start) { NewSectionEndDateTextError = "Enddatum liegt vor Abschnittsbeginn."; return; }
|
||||
|
||||
var section = new ParticipationSection { GroupId = _groupId, Label = NewSectionLabel.Trim(), StartDate = start, EndDate = end };
|
||||
_sectionRepo.Save(section);
|
||||
@@ -350,7 +358,6 @@ public partial class ParticipationWizardDialogViewModel : ObservableObject
|
||||
});
|
||||
}
|
||||
|
||||
SectionValidationMessage = "";
|
||||
NewSectionLabel = $"Abschnitt {_sectionList.Count + 1}";
|
||||
BuildTimeline(CurrentStudentId);
|
||||
BuildSections(CurrentStudentId);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using LehrerApp.Core.Services;
|
||||
using LehrerApp.Desktop.Services;
|
||||
using LehrerApp.Desktop.ViewModels.Groups;
|
||||
using LehrerApp.Desktop.ViewModels.Settings;
|
||||
using LehrerApp.Desktop.ViewModels.Students;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace LehrerApp.Desktop.ViewModels;
|
||||
|
||||
@@ -17,13 +19,15 @@ public partial class MainWindowViewModel : ObservableObject
|
||||
[ObservableProperty] private string _currentSchoolYear = "";
|
||||
|
||||
public SyncStatusViewModel SyncStatus { get; }
|
||||
public ObservableCollection<ToastItem> Toasts { get; }
|
||||
|
||||
public MainWindowViewModel(IServiceProvider services,
|
||||
DashboardViewModel dashboard, SchoolYearService sy,
|
||||
SyncStatusViewModel syncStatus)
|
||||
SyncStatusViewModel syncStatus, NotificationService notifications)
|
||||
{
|
||||
_services = services;
|
||||
SyncStatus = syncStatus;
|
||||
Toasts = notifications.Toasts;
|
||||
CurrentSchoolYear = sy.CurrentSchoolYear();
|
||||
CurrentPage = dashboard;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public partial class SettingsViewModel : ObservableObject
|
||||
|
||||
[ObservableProperty] private string _newName = "";
|
||||
[ObservableProperty] private string _newShort = "";
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _newNameError = "";
|
||||
|
||||
public ObservableCollection<SubjectListItem> Subjects { get; } = [];
|
||||
|
||||
@@ -41,7 +41,7 @@ public partial class SettingsViewModel : ObservableObject
|
||||
|
||||
[ObservableProperty] private string _newTemplateName = "";
|
||||
[ObservableProperty] private string _newTemplateGradingSystemName = "Noten 1–6";
|
||||
[ObservableProperty] private string _templateValidationMessage = "";
|
||||
[ObservableProperty] private string _newTemplateNameError = "";
|
||||
|
||||
public List<string> GradingSystemOptions { get; } = ["Noten 1–6", "Punkte 0–15"];
|
||||
public ObservableCollection<GradingKeyTemplateEditItem> GradingKeyTemplateList { get; } = [];
|
||||
@@ -93,7 +93,7 @@ public partial class SettingsViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void AddGradingKeyTemplate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NewTemplateName)) { TemplateValidationMessage = "Vorlagenname erforderlich."; return; }
|
||||
if (string.IsNullOrWhiteSpace(NewTemplateName)) { NewTemplateNameError = "Vorlagenname erforderlich."; return; }
|
||||
|
||||
var system = NewTemplateGradingSystemName == "Punkte 0–15"
|
||||
? GradingSystem.Points0To15 : GradingSystem.Grades1To6;
|
||||
@@ -109,7 +109,7 @@ public partial class SettingsViewModel : ObservableObject
|
||||
_gradingKeyTemplates.Save(template);
|
||||
GradingKeyTemplateList.Add(new GradingKeyTemplateEditItem(template, _gradingKeyTemplates, _grading));
|
||||
NewTemplateName = "";
|
||||
TemplateValidationMessage = "";
|
||||
NewTemplateNameError = "";
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -132,17 +132,17 @@ public partial class SettingsViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void AddSubject()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NewName)) { ValidationMessage = "Name erforderlich."; return; }
|
||||
if (string.IsNullOrWhiteSpace(NewName)) { NewNameError = "Name erforderlich."; return; }
|
||||
try
|
||||
{
|
||||
_subjects.Save(new Subject { Name = NewName.Trim(), ShortName = NewShort.Trim() });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
ValidationMessage = ex.Message;
|
||||
NewNameError = ex.Message;
|
||||
return;
|
||||
}
|
||||
NewName = ""; NewShort = ""; ValidationMessage = "";
|
||||
NewName = ""; NewShort = ""; NewNameError = "";
|
||||
LoadSubjects();
|
||||
}
|
||||
|
||||
@@ -156,10 +156,10 @@ public partial class SettingsViewModel : ObservableObject
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
ValidationMessage = ex.Message;
|
||||
NewNameError = ex.Message;
|
||||
return;
|
||||
}
|
||||
ValidationMessage = "";
|
||||
NewNameError = "";
|
||||
if (CatalogSubject?.Id == item.Id) CatalogSubject = null;
|
||||
LoadSubjects();
|
||||
}
|
||||
@@ -362,7 +362,8 @@ public partial class GradingKeyTemplateEditItem : ObservableObject
|
||||
|
||||
[ObservableProperty] private string _newGrade = "";
|
||||
[ObservableProperty] private double _newMinPercent;
|
||||
[ObservableProperty] private string _validation = "";
|
||||
[ObservableProperty] private string _newGradeError = "";
|
||||
[ObservableProperty] private string _newMinPercentError = "";
|
||||
[ObservableProperty] private string _completenessWarning = "";
|
||||
|
||||
public ObservableCollection<GradingKeyEntryVm> Entries { get; } = [];
|
||||
@@ -384,10 +385,15 @@ public partial class GradingKeyTemplateEditItem : ObservableObject
|
||||
[RelayCommand]
|
||||
private void AddEntry()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NewGrade)) { Validation = "Bezeichnung erforderlich."; return; }
|
||||
if (NewMinPercent is < 0 or > 100) { Validation = "Prozentgrenze muss zwischen 0 und 100 liegen."; return; }
|
||||
if (_template.Entries.Any(e => Math.Abs(e.MinPercent - NewMinPercent) < 0.0001))
|
||||
{ Validation = "Diese Prozentgrenze existiert bereits."; return; }
|
||||
NewGradeError = ""; NewMinPercentError = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(NewGrade)) { NewGradeError = "Bezeichnung erforderlich."; valid = false; }
|
||||
if (NewMinPercent is < 0 or > 100) { NewMinPercentError = "Muss zwischen 0 und 100 liegen."; valid = false; }
|
||||
else if (_template.Entries.Any(e => Math.Abs(e.MinPercent - NewMinPercent) < 0.0001))
|
||||
{ NewMinPercentError = "Diese Prozentgrenze existiert bereits."; valid = false; }
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
var entry = new GradingKeyEntry { Grade = NewGrade.Trim(), MinPercent = NewMinPercent };
|
||||
_template.Entries.Add(entry);
|
||||
@@ -396,7 +402,7 @@ public partial class GradingKeyTemplateEditItem : ObservableObject
|
||||
|
||||
Entries.Clear();
|
||||
foreach (var e in _template.Entries) Entries.Add(new GradingKeyEntryVm(e, DeleteEntry));
|
||||
NewGrade = ""; NewMinPercent = 0; Validation = "";
|
||||
NewGrade = ""; NewMinPercent = 0;
|
||||
RecomputeCompleteness();
|
||||
}
|
||||
|
||||
|
||||
@@ -361,7 +361,9 @@ public partial class AddStudentDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private string _dateOfBirthText = "";
|
||||
[ObservableProperty] private string _selectedGender = "";
|
||||
[ObservableProperty] private string _notes = "";
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _lastNameError = "";
|
||||
[ObservableProperty] private string _firstNameError = "";
|
||||
[ObservableProperty] private string _dateOfBirthError = "";
|
||||
|
||||
public List<string> GenderOptions { get; } = ["", "M – männlich", "W – weiblich", "D – divers"];
|
||||
public List<string> RelationPresets { get; } = ["Schüler/in", "Mutter", "Vater", "Elternteil", "Erziehungsberechtigte/r", "Sonstige"];
|
||||
@@ -380,8 +382,11 @@ public partial class AddStudentDialogViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void Save()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(LastName)) { ValidationMessage = "Nachname erforderlich."; return; }
|
||||
if (string.IsNullOrWhiteSpace(FirstName)) { ValidationMessage = "Vorname erforderlich."; return; }
|
||||
LastNameError = ""; FirstNameError = ""; DateOfBirthError = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(LastName)) { LastNameError = "Nachname erforderlich."; valid = false; }
|
||||
if (string.IsNullOrWhiteSpace(FirstName)) { FirstNameError = "Vorname erforderlich."; valid = false; }
|
||||
|
||||
DateOnly? dob = null;
|
||||
if (!string.IsNullOrWhiteSpace(DateOfBirthText))
|
||||
@@ -389,11 +394,13 @@ public partial class AddStudentDialogViewModel : ObservableObject
|
||||
if (!DateOnly.TryParseExact(DateOfBirthText, "dd.MM.yyyy", null,
|
||||
System.Globalization.DateTimeStyles.None, out var d))
|
||||
{
|
||||
ValidationMessage = "Geburtsdatum im Format TT.MM.JJJJ."; return;
|
||||
DateOfBirthError = "Format TT.MM.JJJJ."; valid = false;
|
||||
}
|
||||
dob = d;
|
||||
else dob = d;
|
||||
}
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
Result = new Student
|
||||
{
|
||||
FirstName = FirstName.Trim(),
|
||||
@@ -456,7 +463,8 @@ public partial class ContactEditDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private string _invalidSinceText = "";
|
||||
[ObservableProperty] private string _selectedInvalidReason = "";
|
||||
[ObservableProperty] private string _invalidReasonDetails = "";
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
[ObservableProperty] private string _nameError = "";
|
||||
[ObservableProperty] private string _invalidSinceError = "";
|
||||
|
||||
public string DialogTitle => _source is null ? "Kontakt anlegen" : "Kontakt bearbeiten";
|
||||
public List<string> RelationPresets { get; } =
|
||||
@@ -494,10 +502,13 @@ public partial class ContactEditDialogViewModel : ObservableObject
|
||||
[RelayCommand]
|
||||
private void Save()
|
||||
{
|
||||
NameError = ""; InvalidSinceError = "";
|
||||
var valid = true;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Name))
|
||||
{
|
||||
ValidationMessage = "Name erforderlich.";
|
||||
return;
|
||||
NameError = "Name erforderlich.";
|
||||
valid = false;
|
||||
}
|
||||
|
||||
DateOnly? invalidSince = null;
|
||||
@@ -506,12 +517,14 @@ public partial class ContactEditDialogViewModel : ObservableObject
|
||||
if (!DateOnly.TryParseExact(InvalidSinceText, "dd.MM.yyyy", null,
|
||||
System.Globalization.DateTimeStyles.None, out var parsedDate))
|
||||
{
|
||||
ValidationMessage = "Ungültig seit im Format TT.MM.JJJJ angeben.";
|
||||
return;
|
||||
InvalidSinceError = "Format TT.MM.JJJJ.";
|
||||
valid = false;
|
||||
}
|
||||
invalidSince = parsedDate;
|
||||
else invalidSince = parsedDate;
|
||||
}
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
Result = new Contact
|
||||
{
|
||||
Id = _source?.Id ?? Guid.NewGuid(),
|
||||
|
||||
Reference in New Issue
Block a user