2010-11-28 23 views
10

Rails tiene una validación de singularidad muy conveniente.Validación ASP.NET MVC de unicidad

ASP.NET MVC no lo hace.

Necesito asegurarme de que la dirección de correo electrónico que ha ingresado un usuario aún no ha sido registrada por nadie.

Solo puedo ver una forma de hacer este tipo de validación: crear un nuevo objeto de contexto de datos en la clase UniqueAttribute.

Pero me temo que desperdiciar memoria en un nuevo objeto de contexto de datos solo para una validación es peligroso.

¿Estoy equivocado? ¿Hay una mejor manera de hacer eso?

actualización

Esto es lo que tengo hasta ahora

public class UniqueEmailAttribute : ValidationAttribute { 
    public override bool IsValid(object value) { 
     DataContext db = new DataContext(); 
     var userWithTheSameEmail = db.Users.SingleOrDefault(
      u => u.Email == (string)value); 
     return userWithTheSameEmail == null; 
    } 
} 

// Usage 
[UniqueEmail(ErrorMessage="This e-mail is already registered")] 
public string Email { get; set; } 

Hay dos problemas.

  1. Sería bueno tener una sola clase UniqueAttribute, no clases separadas para los mensajes de correo electrónico, nombres de usuario, etc. ¿Cómo puedo hacer eso?

  2. Crear un nuevo contexto de datos cada vez que necesite validar un solo atributo.

SOLUCIÓN

Así que al final me creado una restricción única en la tabla y ahora sólo hay que interceptar SqlException en el repositorio usuarios. Funciona muy bien y es probablemente más eficiente que buscar el mismo nodo en toda la tabla. ¡Gracias!

+2

Rails vs ASP.NET MVC es como comparar manzanas con naranjas, no son lo mismo. ASP.NET MVC no tiene una capa de persistencia de datos formal, tiene que elegir uno de los muchos, y luchar con ese – TFD

+0

@TFD, ese es un buen punto. Estoy de acuerdo, no hay capa de datos, por lo que el DataContext debe almacenarse en algún lugar, de eso se trata mi pregunta. – Alex

+0

1] De forma predeterminada, el nombre de propiedad al que se aplica el atributo se envía al método de acción como un parámetro de cadena de consulta. – swapneel

Respuesta

1

Una manera infalible de hacerlo es crear un atributo de validación que consultaría la base de datos para la dirección de correo electrónico. Sin duda agregaría latencia.

Una alternativa sería crear una restricción única en la tabla e interceptar SqlException.

+12

En realidad, su método "infalible" no lo es. Crea una condición de carrera.Dos procesos de servidor separados podrían consultar la misma dirección de correo electrónico al mismo tiempo y se les informará a ambos que no está en el DB. Entonces ambos intentarían salvarlo. Solo uno ganaría. El único método infalible para garantizar este tipo de exclusividad es una restricción única en la base de datos. – mlibby

+0

He actualizado mi publicación con la clase que funciona, pero todavía no es lo que quiero. ¿Será una restricción única el mejor rendimiento? – Alex

+0

mcl, no debería ser un problema si está utilizando la misma unidad de trabajo/conexión para cada solicitud HTTP, que generalmente es la práctica recomendada. Pero ciertamente es algo de lo que debes estar consciente. –

7

Mvc 3 Relaease candidate tiene nuevos Atributos de validación nuevos como una validación remota, donde puede registrar un método para la validación en el cliente (jquery).

ver más abajo ejemplo- RemoteAttribute

El nuevo atributo de validación RemoteAttribute se aprovecha de validador remota del jQuery Validación del plug-in, que permite la validación del lado del cliente para llamar a un método en el servidor que ejecuta la lógica de validación real .

En el siguiente ejemplo, la propiedad UserName tiene aplicado RemoteAttribute. Al editar esta propiedad en una vista de edición, la validación del cliente llamará a una acción llamada UserNameAvailable en la clase UsersController para validar este campo.

public class User { 
    [Remote("UserNameAvailable", "Users")] 
    public string UserName { get; set; } 
} 

El siguiente ejemplo muestra el controlador correspondiente.

public class UsersController { 
     public bool UserNameAvailable(string username) { 
      return !MyRepository.UserNameExists(username); 

     } 
    } 

Mvc 3

ACTUALIZACIÓN

public bool UserNameAvailable(string Propertyname) 
    { 
     if (Request.QueryString[0]= "UserName") 
     { 
      //validate username 
     } 
     elseif (Request.QueryString[0]= "Email") 
     { 
      //Validate Email 
     } 

    } 
+0

Tenga en cuenta que esto solo funciona para la validación del lado del cliente. Necesita extender RemoteAttribute para agregar validación del lado del servidor. Ver: http://www.codeproject.com/Articles/682434/Custom-Remote-Attribute-for-Client-Server-Validati – Kurren

2

ASP.Net tiene una característica que puede comprobar automáticamente la singularidad de la dirección de correo electrónico de un usuario cuando un usuario se registra. Es el servicio de Membresía de ASP.Net y puede usarlo para hacer lo que quiera, incluso si no utiliza todas las características del mismo.

Si no está utilizando la función de miembro de pleno derecho en su aplicación MVC, entonces todo lo que necesita hacer es utilizar

Membership.FindUsersByEmail (emailYouAreLookingFor);

Si aparece algún valor, usted sabe que la dirección no es única. Si utiliza el servicio de Membresía para crear usuarios, entonces el servicio de Membresía comprobará AUTOMÁTICAMENTE y le devolverá un código si la dirección de correo electrónico del usuario no es única.

El servicio de suscripción se encuentra en la zona System.Web.Security por lo que tendría un

usando System.Web.Security;

referencia en su controlador.

Aquí es un ejemplo

  MembershipCreateStatus createStatus = MembershipService.CreateUser(UserName, Password, Email); 

      if (createStatus == MembershipCreateStatus.DuplicateEmail) 
      { 

        //do something here 
      } 
      else 
      { 
        //do something here 

      } 

espero que esto ayude!

Cuestiones relacionadas