Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

260
Views
FluentValidation: validar solo se establece una propiedad

Tengo problemas para implementar un validador para una clase, donde solo se debe establecer una propiedad.

Digamos que tenemos la siguiente clase:

 public class SomeClass { public DateTime SomeDate {get; set;} public IEnumerable<int> FirstOptionalProperty {get; set;} public IEnumerable<int> SecondOptionalProperty {get; set;} public IEnumerable<int> ThirdOptionalProperty {get; set;} }

Esta clase tiene una propiedad obligatoria: SomeDate . Otras propiedades son opcionales y solo se puede establecer una, por ejemplo, si se establece FirstOptionalProperty - SecondOptionalProperty y ThirdOptionalProperty deben ser nulas, si se establece SecondOptionalProperty - FirstOptionalProperty y ThirdOptionalProperty deben ser nulas y así sucesivamente.

En otras palabras: si se establece uno de los accesorios de IEnumerable, otros IEnumerables deben ser nulos.

¿Algún consejo/idea sobre la implementación del validador para este tipo de clase? Lo único que se me ocurrió fue escribir fragmentos de reglas When , pero esta forma de escribir código es propensa a errores y el resultado se ve feo.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Puede aprovechar la sobrecarga Must que le da acceso a todo el objeto de la clase para que pueda realizar una validación de propiedad con otras propiedades. Consulte la regla FluentValidation para varias propiedades para obtener más detalles.

 public class SomeClassValidator : AbstractValidator<SomeClass> { private const string OneOptionalPropertyMessage = "Only one of FirstOptionalProperty, SecondOptionalProperty, or ThirdOptionalProperty can be set."; public SomeClassValidator() { RuleFor(x => x.FirstOptionalProperty) .Must(OptionalPropertiesAreValid) .WithMessage(OneOptionalPropertyMessage); RuleFor(x => x.SecondOptionalProperty) .Must(OptionalPropertiesAreValid) .WithMessage(OneOptionalPropertyMessage); RuleFor(x => x.ThirdOptionalProperty) .Must(OptionalPropertiesAreValid) .WithMessage(OneOptionalPropertyMessage); } // this "break out" method only works because all of the optional properties // in the class are of the same type. You'll need to move the logic back // inline in the Must if that's not the case. private bool OptionalPropertiesAreValid(SomeClass obj, IEnumerable<int> prop) { // "obj" is the important parameter here - it's the class instance. // not going to use "prop" parameter. // if they are all null, that's fine if (obj.FirstOptionalProperty is null && obj.SecondOptionalProperty is null && obj.ThirdOptionalProperty is null) { return true; } // else, check that exactly 1 of them is not null return new [] { obj.FirstOptionalProperty is not null, obj.SecondOptionalProperty is not null, obj.ThirdOptionalProperty is not null } .Count(x => x == true) == 1; // yes, the "== true" is not needed, I think it looks better } }

Puede modificar la función de verificación. Tal como está actualmente, si establece 2 o más de las propiedades opcionales, TODAS arrojarán un error. Eso puede o no estar bien para sus necesidades.

También podría crear una RuleFor SOLAMENTE para la primera propiedad opcional, en lugar de para todas ellas, ya que todas las propiedades ejecutarán el mismo código IsValid y devolverán el mismo mensaje, su usuario podría confundirse un poco si recibe un mensaje de error para OptionalProperty1 pero no proporcionaron ese.

La desventaja de este enfoque es que necesita saber en tiempo de compilación cuáles son todas sus propiedades (para que pueda escribir el código), y necesita mantener este validador si agrega/elimina entradas opcionales. Este inconveniente puede o no ser importante para usted.

over 4 years ago · Santiago Trujillo Report

0

una cosa que me viene a la mente es usar la reflexión aquí:

 SomeClass someClass = new SomeClass { SomeDate = DateTime.Now, FirstOptionalProperty = new List<int>(), //SecondOptionalProperty = new List<int>() // releasing this breakes the test }; var info = typeof(SomeClass).GetProperties() .SingleOrDefault(x => x.PropertyType != typeof(DateTime) && x.GetValue(someClass) != null);

básicamente, si la info es null , se crearon instancias de más de 1 de las propiedades opcionales

over 4 years ago · Santiago Trujillo Report

0

Yo usaría una función de ayuda para esto.

 private static bool OnlyOneNotNull(params object[] properties) => properties.Count(p => p is not null) == 1;

Lo usarías así.

 SomeClass s = new SomeClass(); /* ... */ if(!OnlyOneNotNull(s.FirstOptionalProperty, s.SecondOptionalProperty, s.ThirdOptionalProperty)) { /* handle error case */ }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!