2011-04-13 11 views
5

Tengo dos clases que estoy usando como modelo de dos vistas diferentes. Puedes ver que la segunda clase contiene una instancia de la primera. El primero contiene atributos de validación remota.¿Cómo puedo reutilizar un método de validación remota cuando el nombre del parámetro debe ser diferente?

[MetadataType(typeof(ExceptionLogModel.EmailRecipientMetadata))] 
public class EmailRecipientViewModel 
{ 
    public int EmailRecipientID { get; set; } 

    [Remote("ValidateEmailRecipientNameUniqueness", "EmailRecipient", ErrorMessage = "Name is not unique.")] 
    public string Name { get; set; } 

    [Remote("ValidateEmailRecipientEmailUniqueness", "EmailRecipient", ErrorMessage = "Email is not unique.")] 
    public string Email { get; set; } 
} 

public class EmailRecipientChoices 
{ 
    public List<EmailRecipient> UnselectedEmailRecipients { get; set; } 
    public List<EmailRecipient> SelectedEmailRecipients { get; set; } 
    public EmailRecipientViewModel EmailRecipient { get; set; } 
} 

Cuando estas validaciones desencadenan en el navegador, dos solicitudes diferentes se hacen en función de la clase de la vista utilizada. Se puede ver que los nombres de los parámetros de cadena de consulta son diferentes:

http://localhost:55327/EmailRecipient/ValidateEmailRecipientNameUniqueness?Name=sdhsdgh 

http://localhost:55327/EmailRecipient/ValidateEmailRecipientNameUniqueness?EmailRecipient.Name=sdhsdgh 

Aquí es la versión actual de mi método de acción que no funciona con el segundo URL:

public JsonResult ValidateEmailRecipientNameUniqueness(string name) 
{ 
    var isValid = !_emailRecipientRepo.NameExists(name); 

    return Json(isValid, JsonRequestBehavior.AllowGet); 
} 

Cuando se utiliza el segundo URL , el parámetro de nombre será nulo. He leído que debería poder agregar un atributo Bind a ese parámetro y agregar un prefijo, pero esto tampoco funciona. Incluso intenté establecer el prefijo en EmailRecipient. por si necesitaba el punto. También lo intenté con una N mayúscula en Name por si acaso. No vayas. ¡Agregar esto también lo rompe para la otra URL!

public JsonResult ValidateEmailRecipientNameUniqueness([Bind(Prefix = "EmailRecipient")] string name) 

soluciones posibles

que podrían tener el método de tomar una instancia de EmailRecipientViewModel y crear una IModelBinder por ella en la que pude buscar ya sea la convención de nombres y asignarlo a la instancia. Esto parece más trabajo de lo que debería ser.

que podría utilizar la sobrecarga para @Html.EditorFor() y que lo utilice "Nombre" para htmlFieldName, y también utilizar en lugar de @Html.ValidationMessage("Name")ValidationMessageFor. El único inconveniente de esto son los posibles conflictos de nomenclatura, pero eso no es un gran problema. Solo tendría que usar un nombre único para todas las instancias de esta clase que se usen. Actualización: En realidad, si hago esto, se rompe algo cuando publico el formulario porque cambié los nombres. Eso no es bueno.

...

acabo dado cuenta de que yo pudiera tener el método de toma ningún parámetro, y accede a la cadena de consulta manualmente. Esta es una solución bastante simple, pero no entiendo el buen parámetro.

string name = Request.QueryString[ "Name" ] ?? Request.QueryString[ "EmailRecipient.Name" ]; 

Esto es tan fácil que probablemente solo voy a usar esto. Sin embargo, dado que ya tengo esta pregunta mecanografiada, preguntaré: ¿hay una solución más elegante?

Respuesta

1

No hay realmente una manera limpia de hacer esto sin rodar su propia validación o carpeta de modelo. Piense que es como el enlace del modelo, la carpeta de modelo necesita saber el nombre de lo que está entrando, lo mismo para la validación remota. Un enfoque que podría tomar es crear dos métodos separados de validación remota en su controlador que terminen llamando al único método que realmente hace todo el trabajo de validación.

1

Bueno, sé que es tarde, pero hay una solución más elegante:

public JsonResult ValidateEmailRecipientNameUniqueness (EmailRecipient recipient) 
{ 
    string name = recipient.Name; 
    var isValid = !_emailRecipientRepo.NameExists(name); 
    return Json(isValid, JsonRequestBehavior.AllowGet); 
} 

En otras palabras, utilizar el modelo en sí. Va a enlazar correctamente la propiedad name y solo necesita este valor.

+0

Eso no funciona cuando el cuadro de texto se llama simplemente "nombre". Ese es el problema.Tenía dos cuadros de texto diferentes que querían usar el mismo método de validación. – Glazed

+0

Acabo de probarlo ahora de mi lado. Utilicé Fiddler y puedo confirmar: funciona sin ningún prefijo. – SmartDev

+0

@Glazed 5.0.0 ... – SmartDev

Cuestiones relacionadas