Si no te gusta utilizar data anotations, o por cualquier motivo, no puedes agregarlas a una clase, y necesitas hacer la validación de un formulario, te va a tocar hacer un poco de código, pero bueno, no es mucho y es bastante fácil de entender y aprender.
Exponiendo un ejemplo
En este ejemplo, vamos a utilizar una clase llamada ExampleModelFromExternalDll para simular un supuesto modelo del que no podemos modificar el codigo y agregar, por ejemplo, data anotations. Y además no podemos, o no sabemos, utilizar otros mecanismos de validación, como puede ser FluentValidator, o no podemos agregarlo al proyecto por el motivo que sea.
En estas líneas vamos a ver un pequeño ejemplo de cómo hacer la validación de un EditForm y que por supuesto puede ser encapsulado para poder ser reutilizado.
Pasos
1. Crear una instancia del model ExampleModelFromExternalDll como Model = new(). Esta va a contener los datos.
2. Declarar una variable del tipo Microsoft.AspNetCore.Components.Forms.EditContext como FormContext..Esta va a controlar los datos dentro del edit form.
3. Declarar una variable del tipo Microsoft.AspNetCore.Components.Forms.ValidationMessageStore como ValidationMessageStore donde se gestionaran los mensajes por propiedad a mostrar.
string Messages;
ExampleModelFromExternalDll Model = new();
EditContext FormContext;
ValidationMessageStore ValidationMessageStore;
4. En ese ejemplo desde el evento OnInitialiced() instanciaremos las varialbles y registraremos un par de eventos
protected override void OnInitialized()
{
FormContext = new EditContext(Model);
FormContext.OnFieldChanged += FormContext_OnFieldChanged; //se disparará cada vez que se cambie una propiedad
FormContext.OnValidationRequested += FormContext_OnValidationRequested; //se disparará cuando se quiera validar el formulario
ValidationMessageStore = new ValidationMessageStore(FormContext); //enlazar los mensajes al cotexto que se está utilizando
}
5. Crearemos los manejadores de los eventos
private void FormContext_OnValidationRequested(object sender, ValidationRequestedEventArgs e)
{
//hacer la validación
Messages = "";
ValidationMessageStore.Clear();
if(string.IsNullOrWhiteSpace(Model.FirstName))
ValidationMessageStore.Add(new FieldIdentifier(Model, nameof(Model.FirstName)), "First name required");
if(string.IsNullOrWhiteSpace(Model.Email))
ValidationMessageStore.Add(new FieldIdentifier(Model, nameof(Model.Email)), "Email required");
FormContext.NotifyValidationStateChanged();
}
private void FormContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
{
//hacer la validación
Messages = "";
ValidationMessageStore.Clear(e.FieldIdentifier);
switch(e.FieldIdentifier.FieldName)
{
case nameof(Model.FirstName):
if(string.IsNullOrWhiteSpace(Model.FirstName))
ValidationMessageStore.Add(e.FieldIdentifier, "First name required");
break;
case nameof(Model.Email):
if(string.IsNullOrWhiteSpace(Model.Email))
ValidationMessageStore.Add(e.FieldIdentifier, "Email required");
if(!Model.Email.Contains("@"))
ValidationMessageStore.Add(e.FieldIdentifier, "Email not valid");
break;
}
FormContext.NotifyValidationStateChanged();
}
6. Por último crearemos un método de ejemplo para utilizar cuando se quiera enviar el formulario
void SubmitForm()
{
Messages = "Form will be send!";
}
7. Ahora creamos la vista en la página de la forma más común
< div class="container">
< h1 class="title">Validation form demo
< EditForm EditContext=FormContext OnValidSubmit=SubmitForm>
< div class="field">
< label class="label">First Name
< div class="control">
< InputText @bind-Value=Model.FirstName class="input" />
< ValidationMessage For="() => Model.FirstName" />
< /div>
< /div>
< div class="field">
< label class="label">Email
< div class="control">
< InputText @bind-Value=Model.Email class="input" type="email" />
< ValidationMessage For="() => Model.Email" />
< /div>
< /div>
< div class="field">
< div class="control">
< button class="button is-success">Submit
< /div>
< label class="label">@Messages
< /div>
< /EditForm>
< /div>
Y eso es todo amigos
Bueno no hay mucho más que explicar, ya os comenté que era bastante sencillo y fácil de entender, pero que si vas a hacer esto cada cez es mucho trabajo. Lo mejor es buscar comoencapsularlo en un componente. Pero eso ya en otro blog.
Para descargar el código de ejemplio pues hacerlo en este Github.