2009-11-23 56 views
5

si alguien tiene mucha experiencia con [C#] FluentValidation y tiene alguna idea para la siguiente pregunta, cualquier ayuda sería muy apreciada.Validar 2 listas usando FluentValidation

Tengo 2 listas genéricas (ambas con cadenas de tipo de datos) - "Nombre" y "Url". Ambos tienen la misma cantidad de elementos, por lo que los elementos indexados coinciden, es decir, los nombres [0] se correlacionan con las URL [0].

El único problema que tengo es la validación de elementos vacíos en cada lista. Las reglas que necesito son:

si un elemento está vacío en Nombre [2], entonces la URL [2] no debería estar vacía. si un elemento está vacío en Url [2], entonces Nombre [2] no debe estar vacío. si ambos están vacíos, entonces no queremos validar, queremos ignorar.

Nota: He utilizado el índice 2 en el ejemplo anterior, pero podría ser cualquier cosa

Hasta ahora tengo:

RuleFor(f => f.Names).Must(d => d.All(s => !String.IsNullOrEmpty(s))) 
       .WithMessage("Names cannot be empty.") 

RuleFor(f => f.URLs).Must(urls => urls.All(s => !String.IsNullOrEmpty(s))) 
       .WithMessage("URLs cannot be empty.") 

Esto comprueba que no hay elementos están vacíos en ninguna de las listas, sin embargo, debo ser capaz de no validar elementos para estar vacío en una lista si el elemento correlativo en la otra también está vacío (si ambos están vacíos, entonces solo queremos ignorarlo).

¿Alguna idea?

Respuesta

8

Terminé usando el siguiente código FluentValidation para comprobar los artículos corrosponding en cada lista, muchas gracias a Guvante ya que se inspiró en su pseudo-código :)

RuleFor(f => f.Names).Must((f, d) => 
      { 
       for (int i = 0; i < d.Count; i++) 
       { 
        if ((String.IsNullOrEmpty(d[i]) && 
         !String.IsNullOrEmpty(f.URLs[i]))) 
         return false; 
       } 

       return true; 
      }) 
      .WithMessage("Names cannot be empty."); 

      RuleFor(f => f.URLs).Must((f, u) => 
      { 
       for (int i = 0; i < u.Count; i++) 
       { 
        if ((String.IsNullOrEmpty(u[i]) && 
         !String.IsNullOrEmpty(f.Names[i]))) 
         return false; 
       } 

       return true; 
      }) 
      .WithMessage("URLs cannot be empty."); 
+1

Muchas gracias por publicar esto. Estaba tirando de mi cabello. Esto funciona muy bien si está validando que al menos en la casilla de verificación se ha marcado: 'RuleFor (x => x.AvailableCompanies) .Must ((f, d) => {return d.Find (h => h.Checked == true)! = null;}). WithMessage ("Seleccione al menos una compañía"); ' – brenjt

1

Aquí hay un pseudocódigo de una solución de fuerza bruta. (No puedo pensar en ninguna forma LINQ de hacer comparaciones indexadas) Perdón por la matanza de la sintaxis Fluent.

Must(Names.Length == URLs.Length).WithMessage("Names must be equal in size to URLs"); 
for (int i = 0; i < Name.Length; i++) 
{ 
    Must(string.IsNullOrEmpty(Names[i]) ^^ string.IsNullOrEmpty(URLs[i])).WithMessage("Either Name and URL must be non-empty, or both must be empty, index = " + i); 
} 

Esperemos que se obtiene la esencia de la misma, es posible que también desee ver en los métodos generales de LINQ, es probable que echaba de menos. Básicamente, quieres hacer una unión y luego verificar los resultados no válidos en la lista fusionada, pero de nuevo no estoy seguro de cómo hacer una fila por fila y no simplemente muchos se unen.

+0

@Guvante: Gracias, su pseudo el código hizo rodar la pelota en la dirección correcta (ver la respuesta publicada). +1 para ti :) – Scozzard

Cuestiones relacionadas