← All courses
UI · Free course

Validation in Wisej.NET

Every business app lives or dies on the data people type into it. This beginner course teaches you to validate that input the Wisej.NET way — catching mistakes while the user edits, explaining them in plain language, and making sure bad data can never be saved — all built around the ValidationClinic project, a customer intake form and an editable contacts grid. Seven modules start with the validation lifecycle — Validating, Validated, e.Cancel, AutoValidate and ValidateChildren — then move to ErrorProvider feedback and visible summaries, the Validation extender and its built-in rules, and custom validation with reusable services and ValidationRule classes. From there you'll validate the model itself with data binding, DataAnnotations and IDataErrorInfo, validate DataGridView cells and rows, and finish with a complete Save pipeline and a custom error provider in the capstone. It's written for developers who know basic C# and are starting to build Wisej.NET forms.

Validate forms, grids and data-bound editors clearly — events, ErrorProvider, validation rules, model errors and grid cells.

Start this free course

Also available in: DeutschFrançaisItalianoEspañol

Curriculum

Module 1: Validation Fundamentals in Wisej.NET

Module 1 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the validation fundamentals walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    What validation means in a server-side Wisej.NET UI: the Validating and Validated lifecycle, cancelling invalid input with e.Cancel, AutoValidate focus behavior, CausesValidation on Cancel buttons, and ValidateChildren as the guard on Save. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonWhen validation runs, and what stops a bad save · 14 min

    When validation runs, and what stops a bad save — a guided Module 1 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    Build the ValidationClinic intake form around two opportunities to catch mistakes: when the user leaves a field, and when the user saves. In Wisej.NET, these checks work together so an untouched field cannot escape validation.

    Run quick checks in the Validating event, before the user moves on. The browser reports the focus change, but your C sharp handler executes on the server. Keeping that handler short avoids making ordinary navigation feel slow.

    Use Validating to decide whether the value is acceptable. Cancel the event and explain the problem when it is not. Validated follows only a successful check, making it the appropriate place for cleanup such as trimming an accepted name.

    Set the form’s AutoValidate behavior in its constructor. In each handler, SetError explains a rejected value and e.Cancel rejects it. Clear the message after correction so the interface reflects the current value rather than an earlier mistake.

    Keep focus on an invalid field when the user needs to correct it. Give Cancel a separate escape route by setting CausesValidation to false. Otherwise, validation could prevent someone from abandoning an incomplete form.

    Before writing the customer, call ValidateChildren from Save. This also checks fields the user never visited. If any handler cancels validation, stop the save; only accepted values should reach the write operation and its exception handling.

    Watch the empty name keep focus while the error icon explains why. After correction, the accepted name is trimmed. The malformed email is rejected independently, while Cancel still closes the form without requiring either field to be fixed.

    Test Save before touching the email field. ValidateChildren finds that missing input and prevents the write even though no focus change occurred there. Correct the address and save again to confirm that valid input follows the successful path.

    For this lab, connect field validation, successful-value cleanup, and the final Save check in one intake form. Test Cancel with invalid input as well. Your lab note should explain how these paths prevent bad data without trapping the user.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 1 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — Validating, Validated and a Guarded Save · 45 min

    Objective: Create the ValidationClinic customer intake form with txtName and txtEmail TextBoxes, a Save button and a Cancel button. Attach Validating handlers that set e.Cancel = true and an ErrorProvider message when the name is blank or the email has no @, clear the message when the value is valid, and trim the name in its Validated handler. Set the form's AutoValidate mode, make sure Cancel does not cause validation so the user can always leave, and call ValidateChildren() at the top of btnSave_Click so Save stops when any field is invalid. Finish with a short lab note that explains the focus behavior you chose. Deliverables: Customer intake form with txtName and txtEmail, a Save button and a Cancel button; Validating handlers that set e.Cancel = true and an error message for a blank name and an invalid email; Validated handler that trims the accepted name; Save handler that calls ValidateChildren() and stops when it returns false; Lab note naming the AutoValidate mode chosen and why Cancel still works on an invalid form.

Module 2: Programmatic Validation and ErrorProvider Feedback

Module 2 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the ErrorProvider feedback walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    One ErrorProvider per form, SetError and clearing errors per control, InvalidMessage for simple local feedback, a small FieldValidation result type that keeps rules out of the UI, and a visible validation summary so no error depends on hovering an icon. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonIcons, messages and a summary nobody can miss · 14 min

    Icons, messages and a summary nobody can miss — a guided Module 2 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    Give the contact form feedback that remains useful after the first mistake. One ErrorProvider handles the icons, reusable helpers decide which values are invalid, and a visible summary lets users review every problem together.

    Separate checking a value from displaying its error. Independent field handlers can leave stale icons or clear unrelated messages. A shared approach makes each correction affect the relevant field while preserving problems that still need attention.

    Choose how each message reaches the user. SetError adds an icon beside an input, while InvalidMessage supplies the control’s own tooltip. The summary provides readable text for the whole form, so errors are not discoverable only by hovering.

    Configure a single ErrorProvider for the form, with steady icons placed to the right. Let ValidateEmail return a FieldValidation result instead of changing controls. That separation keeps the rule reusable and leaves presentation to the form.

    Apply processes every result, including successful ones. An empty message removes that field’s old icon; invalid results also populate the summary. Returning whether all results passed gives Save a clear decision before any data is written.

    Match the feedback to the problem. Put a field correction beside its input, explain a business rule in the save summary, and give a system failure its own friendly message. Users should understand which action is available to them.

    Save the form with the three invalid contact fields. Compare the local icons with the summary: both should describe the same remaining problems. The customer-code tooltip demonstrates the alternative display path without replacing the form-wide explanation.

    Correct only the email and leave that field. Its icon and summary entry disappear, but the name and phone messages remain. This demonstrates why individual results must clear individual errors rather than clearing the entire provider.

    Build the helpers, shared ErrorProvider, and Apply method as one feedback path. Verify that correcting one field preserves other errors. Compare the customer-code InvalidMessage with the icons and summary to explain when each presentation is useful.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 2 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — ErrorProvider, Helpers and a Validation Summary · 45 min

    Objective: Turn the ValidationClinic contact form into a programmatic validation form. Create one ErrorProvider for the form with ContainerControl set, NeverBlink and a right-aligned icon, write a FieldValidation record plus ValidateName, ValidateEmail and ValidatePhone helpers that return a message instead of touching the UI, and an Apply method that calls SetError for each result and fills a validationSummaryLabel that is visible only while errors exist. Use InvalidMessage on the customer code field to compare the two feedback styles, and make sure fixing one field clears only that field's error. Deliverables: Form-level ErrorProvider with ContainerControl, BlinkStyle and icon alignment configured; FieldValidation record and ValidateName, ValidateEmail and ValidatePhone helper methods; Apply method that sets or clears each control's error and returns whether all fields are valid; validationSummaryLabel listing every current problem and hidden when there are none; One field using InvalidMessage instead of ErrorProvider, with a note comparing the two.

Module 3: Built-in Validation Rules and the Validation Extender

Module 3 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the Validation extender walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    The Wisej.NET Validation extender: the ValidationRules extended property at design time, SetValidationRules at runtime, the Required, Email, Integer, Decimal, Currency, Telephone and Regex rules, rule order that stops at the first failure, and ErrorProvider or Label display targets. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonDeclare the rules once and let the extender run them · 14 min

    Declare the rules once and let the extender run them — a guided Module 3 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    Move the repeated field rules into the Validation extender. In Wisej.NET, describing each field’s requirements lets the extender run consistent checks for ValidationClinic, while the form remains responsible for presenting useful feedback to the user.

    The extender connects to Validating and Validated on the controls. Instead of repeating the same empty-value check in several handlers, attach rule metadata to each field. The event flow stays familiar while the definitions become easier to share.

    Choose a built-in rule for the kind of value you accept, such as email, integer, currency, or telephone. Use a regular expression when the required pattern needs it. Give each rule an InvalidMessage that explains the correction in the user’s language.

    Add Validation in the designer, then open a control’s ValidationRules collection. Put Required before Email. The collection order is also execution order, so arranging these entries determines which explanation the user receives first.

    A rule failure stops the remaining rules and cancels validation. That is why an empty email should fail Required first: asking for a missing address is more useful than reporting a format problem before any address exists.

    Runtime configuration follows the same rule model. Build the arrays once in ClinicRules, select the display target, then assign each field through SetValidationRules. Keeping the definitions together avoids slightly different copies of the same rule across forms.

    Compare an empty address, a malformed address, and a valid one. Each attempt should produce only the first applicable error. When the value becomes valid, both the icon and summary entry clear, confirming that presentation follows the latest validation result.

    The rules can send feedback to the control, an ErrorProvider, or a label. Choose the target deliberately, then update the summary from the extender’s own events. This keeps the summary synchronized with the checks that actually ran.

    Replace the repeated handlers with shared ClinicRules definitions. Keep Required first and connect the summary to the extender’s events. Your test should show that empty, malformed, and corrected values produce the appropriate message without retaining obsolete feedback.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 3 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — Rules, Rule Order and Display Targets · 45 min

    Objective: Replace the hand-written field handlers in ValidationClinic with the Validation extender. Add a Validation component and an ErrorProvider to the intake form, set ContainerControl and validation.ErrorProvider, then call SetValidationRules in a ConfigureValidationRules method: Required then Email on txtEmail, Required then Integer on txtAge, Required then Telephone on txtPhone, Currency on txtCreditLimit and a Regex rule for the customer code. Put Required first everywhere so the most helpful message wins, hook the extender's Validating event to refresh the summary, and move the rule arrays into a small reusable helper so another form can apply the same configuration. Deliverables: Validation component wired to the form and to an ErrorProvider display target; ConfigureValidationRules method calling SetValidationRules for email, age, phone, credit limit and customer code; Required rule placed first on every required field, with plain-language InvalidMessage text; Extender Validating handler that keeps the validation summary in step with the rules; Reusable rule configuration helper that a second form can call.

Module 4: Custom Validation: Methods, Services and ValidationRule Classes

Module 4 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the custom validation walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    Business rules the built-in rules cannot express: string-returning validation methods, a ContactValidator service that can be tested without the UI, a custom ValidationRule class with OnValidating, OnValidated and OnControlCreated, and cross-field rules that mark every control involved. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonFrom one-off checks to rules you can reuse and test · 14 min

    From one-off checks to rules you can reuse and test — a guided Module 4 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    Module four. Custom validation in Wisej.NET. A form can accept correctly formatted values that still break business rules. Let's fix that.

    Built-in rules check the shape of one value. But a valid date can still come after an end date, and a valid birth date can belong to someone too young. These are business rules. When you compare fields, calculate an age, or check values together, write a custom validation rule.

    Custom validation has three homes. First, a method that returns an error message. Second, a service that returns ValidationMessage records. Third, a class derived from ValidationRule that the validation extender runs. Choose the home that fits the responsibility of your rule.

    ValidateStartEndDates returns an empty string when the dates are valid, or an error message when they are not. Apply that same message to both date pickers. The ContactValidator service has no dependency on controls. It validates the model, so you can test the business logic without the user interface.

    MinimumAgeValidationRule derives from ValidationRule. Its OnValidating method returns true or false. Attach the rule to the birth date picker with SetValidationRules. ApplyModelValidation connects service results to the screen. It maps field names to controls, so each message appears where the user can fix the problem.

    The Save handler runs validation in order. First, check field rules. Then run the validator service and the date rule. Return early if any layer fails. Call the repository only after every check passes. The database should never receive data that your validation has already rejected.

    Now try saving with the start date after the end date. Both pickers show the same error, and the summary displays a single message.

    Correct the end date. Both errors clear together. Because this rule compares two values, both controls share the feedback.

    Enter a birth date from twenty eleven. The minimum age rule rejects it as soon as the user leaves the picker.

    Correct the birth date, and the error clears. Save now runs every validation layer successfully, then stores the contact exactly once.

    For lab four, implement the date check, the validator service, the message mapping, and the minimum age rule.

    Connect them in a Save handler that never saves invalid data.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 4 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — Validator Service and a Custom ValidationRule · 45 min

    Objective: Add custom validation to ValidationClinic in three steps. Write ValidateStartEndDates as a method that returns an empty string when valid and a message when the start date is after the end date, and set that message on both dtpStart and dtpEnd. Move the name, email and birth-date rules into a ContactValidator service that returns a list of ValidationMessage records and map each field name back to its control in ApplyModelValidation. Then create MinimumAgeValidationRule deriving from ValidationRule with a MinimumAge property, override OnValidating to compute the age from the DateTimePicker, attach it to dtpBirthDate through the Validation extender, and run the service in btnSave_Click before anything is saved. Deliverables: ValidateStartEndDates method that sets the same error on both date pickers and clears both when fixed; ContactValidator service returning ValidationMessage records for name, email and birth date; ApplyModelValidation method mapping each field name to its control and the summary; MinimumAgeValidationRule class overriding OnValidating, attached to dtpBirthDate; Save handler that runs field rules, then the validator service, and only then saves.

Module 5: Data-Bound Validation and Model Errors

Module 5 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the data-bound validation walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    Validating the model, not just the controls: BindingSource and EndEdit, DataAnnotations run with Validator.TryValidateObject, mapping MemberNames back to controls, IDataErrorInfo with a data-bound ErrorProvider, BindToDataAndErrors, and the safe save order. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonLet the model say what is valid · 14 min

    Let the model say what is valid — a guided Module 5 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    Module five. Data-bound validation in Wisej.NET. The intake form now edits a Contact Edit Model. Its basic validation rules belong to the data, so the same rules can protect the form, the grid, and other ways of changing a contact.

    A form handler only protects changes made through that form. A grid, an import, or a service can update the same contact without running those handlers. Put the basic rules on the model, then make every save path run them before accepting the data.

    First, finish the current edit. The value still being typed may not have reached the model yet. Call End Edit on the contact binding source before validating. Otherwise, the validator could check an older value even though the user has already corrected the field.

    Data Annotations describe the rules, but they do not run themselves. Try Validate Object applies them and collects the results. Set validate all properties to true. Without that option, only Required is checked, so a malformed email or an out-of-range age could pass.

    The validator returns property names, not controls. Use a field map to connect each result to the correct input. Put the message beside that input and in the summary. If a property has no matching control, keep its message in the summary so the error is still visible.

    There is another approach. A model implementing I Data Error Info answers validation questions for each property. A data-bound Error Provider reads those answers. When switching sources at runtime, Bind To Data And Errors sets the source and member together, avoiding a temporary mismatch.

    Try saving the invalid contact. End Edit first commits the current input to the model. The annotation checks reject the name, email, and age. The field map puts each message beside its input and in the summary. The save path stops before writing anything.

    Correct the values and save again. The checks now pass and the contact is saved. On the I Data Error Info model, clearing the name brings the error icon back through data binding. The form does not need to call Set Error for that change.

    For lab five, bind the editor to the model, finish edits before validating, and map annotation results to the fields and summary. Then connect the I Data Error Info model through Bind To Data And Errors. Verify that invalid data never reaches the repository.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 5 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — DataAnnotations, IDataErrorInfo and EndEdit · 45 min

    Objective: Bind the ValidationClinic intake form to a ContactEditModel through a contactBindingSource and add Required, StringLength, EmailAddress and Range annotations to its Name, Email and Age properties. In btnSave_Click call contactBindingSource.EndEdit() first, run Validator.TryValidateObject with validateAllProperties set to true, and map every ValidationResult member name to its control through a field map and the validation summary. Then implement IDataErrorInfo on a second model, point the ErrorProvider at the binding source with BindToDataAndErrors, and show the same errors appearing through data binding without a hand-written SetError call. Deliverables: ContactEditModel with DataAnnotations bound to the form through a BindingSource; Save handler that calls EndEdit before running Validator.TryValidateObject; Field map that turns ValidationResult member names into control errors and summary lines; IDataErrorInfo model whose errors appear through a data-bound ErrorProvider; BindToDataAndErrors call used when the provider's data source changes at runtime.

Module 6: DataGridView Cell Validation and Row Errors

Module 6 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the grid validation walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    Validation at grid scale: CellValidating with RowIndex, ColumnIndex and the uncommitted FormattedValue, CellValidated for cleanup, cell ErrorText versus row ErrorText, DataError with ThrowException set to false, and new-row and bound-row rules that do not break editing. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonValidate the cell the user is still editing · 14 min

    Validate the cell the user is still editing — a guided Module 6 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    The contacts grid introduces a different editing path from the intake form. A cell has its own editor and validation events, so reuse the same business intent through grid handlers rather than expecting the form’s text-field handlers to run.

    Separate the three problems before choosing a handler. Email format belongs to the cell, nonnumeric age can fail conversion, and a closed contact without a closing date violates a rule across fields. One check cannot explain all three reliably.

    During editing, validate e.FormattedValue because it contains what the user is typing now. The cell’s stored Value still represents the previous committed input. Checking that old value could accept the very mistake the user just introduced.

    Use the column name to select the rule in CellValidating. Clear that cell’s previous message, inspect the edited value, and cancel with a clear explanation when it fails. This keeps the user beside the input that needs correction.

    Place a single-value error on the cell and a relationship error on the row. Reserve DataError for conversion or saving failures that the grid reports. Skip the new-row placeholder, since it is not yet a contact requiring validation.

    ValidateRow updates the row message and the closing-date cell together, making the relationship visible at both levels. In DataError, explain conversion failures in ordinary language and log the exception separately so diagnosis does not become the user’s responsibility.

    Try the malformed email first: validation keeps the edit in place and displays the cell error. Then enter letters for age. The friendly conversion message demonstrates a different failure path, even though both mistakes occurred while editing a cell.

    The closed contact still cannot save until its required closing date is present. The row error keeps that relationship visible, while the placeholder is ignored. Enter the date and save again to verify that correcting the rule permits persistence.

    Build the grid checks around the current edited value, row relationships, and friendly conversion errors. Clear successful cell errors and guard Save against remaining failures. Test each layer separately so a valid cell cannot hide an invalid contact row.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 6 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — Cell Rules, Row Errors and DataError · 45 min

    Objective: Make the ValidationClinic contacts grid refuse bad data. Handle gridContacts.CellValidating: read e.FormattedValue rather than the cell value, clear the cell's ErrorText, then reject a blank or @-less EmailColumn value and an AgeColumn value outside 0 to 120 with e.Cancel = true and a cell ErrorText. Add a ValidateRow method that sets row ErrorText and the ClosedDateColumn cell error when Status is Closed without a closed date, clear stale errors in CellValidated, and handle DataError with ThrowException = false, a friendly cell message and a debug log of the exception. Skip the new placeholder row until it holds user data, and block Save while any row still has an error. Deliverables: CellValidating handler that reads e.FormattedValue and validates the email and age columns; ValidateRow method setting row ErrorText and the closed-date cell error for Closed contacts; CellValidated handler that clears stale cell errors; DataError handler with ThrowException = false, a friendly message and a logged exception; Save guard that skips the placeholder new row and refuses to save while any row has an error.

Module 7: Production Validation UX, Custom Error Providers and Capstone

Module 7 of Validation in Wisej.NET — build forms, grids and data-bound editors that validate input clearly and never save bad data. Read the lesson guide and the lab / exam guide, watch the capstone Save pipeline walkthrough, pass the knowledge check, then complete the hands-on lab in ValidationClinic.

  1. ReadingLesson Guide · 14 min

    Putting every layer together: a boring, repeatable Save pipeline, a custom IErrorProvider that feeds a summary panel, icon and summary providers side by side, ten validation UX rules, and the ValidationClinic capstone that proves where each check belongs. What this means for a developer who knows basic C# and is beginning Wisej.NET form development — and how to read this module.

    Read the lesson guide (PDF)

  2. ReadingLab / Exam Guide · 10 min

    What you'll build in the hands-on lab, the suggested approach, and the required deliverables.

    Read the lesson guide (PDF)

  3. Video lessonOne Save button, every validation layer · 14 min

    One Save button, every validation layer — a guided Module 7 walkthrough, built step by step in ValidationClinic. Runs right here in the player.

    Narration transcript

    Bring the ValidationClinic checks into a single save path. Field, model, business, and grid validation now have to cooperate in Wisej.NET, so a successful check at one layer never bypasses an unresolved problem at another.

    Individually correct validators do not guarantee a correct save. A pending edit may leave the model stale, or a grid error may never reach the form’s checks. Put the stages in a fixed order and require every stage to succeed.

    Reset feedback and finish the current edit before checking fields, the model, business rules, and grid rows. Stop at the first failed stage. This sequence prevents later work from running with invalid input and keeps the eventual write behind all checks.

    Use the IErrorProvider contract to send messages without tying validation to one display. SummaryErrorProvider retains one message for each control and hides its label when none remain. The summary can therefore reflect the same errors as the field feedback.

    Return early when field or model validation fails. If the final save throws, distinguish a duplicate name the user can correct from a system failure they cannot. Route the duplicate to its field and explain other failures calmly.

    Review feedback as part of the workflow, not just as error text. Explain the correction near the field and in the summary, preserve Cancel, and keep technical traces out of user messages. Test missing, invalid, valid, and boundary inputs.

    First, the missing name and malformed email stop the save during field validation. Correct those fields and try again. The model then rejects age one hundred thirty, showing why passing the field checks does not make later checks optional.

    The grid stage catches the remaining email and closed-row problems, and the summary explains both. After those corrections, every stage succeeds and the save completes. The final confirmation now means that the whole validation path passed.

    Deliver the complete save path with the summary provider and shared message helper. Include exception handling that distinguishes correctable input from system failures. Document the test cases so another developer can reproduce both blocked saves and successful corrections.

  4. ReadingAI Coding Exercise · 20 min

    Build this module's ValidationClinic sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.

    Read the lesson guide (PDF)

  5. Knowledge checkModule 7 Knowledge Check · 10 min · Pass mark 80%
  6. Hands-on labLab — Capstone: the Complete Save Pipeline · 45 min

    Objective: Complete the ValidationClinic capstone. Write btnSave_Click as a fixed pipeline: reset the summary, call bindingSource.EndEdit(), stop if ValidateChildren() fails, stop if the DataAnnotations check fails, stop if ContactValidator returns business errors, stop if the contacts grid still has row errors, and only then save inside a try/catch that turns a duplicate name into a field error and any other exception into a friendly message. Create SummaryErrorProvider implementing IErrorProvider, assign it to validation.ErrorProvider, and route errors through a SetError helper that writes to both the icon ErrorProvider and the summary provider. Test required, invalid, valid and boundary values and write a short README explaining the validation design. Deliverables: Save pipeline that runs EndEdit, ValidateChildren, model, business and grid checks before saving; SummaryErrorProvider class implementing IErrorProvider SetError and GetError; SetError helper writing to both the icon ErrorProvider and the summary provider; try/catch around the save separating a duplicate-name error from system failures; README with the validation design and test cases for required, invalid, valid and boundary values.