2011-01-20 16 views
69

ho creato un attributo di convalida personalizzato:Eseguire la convalida lato client per l'attributo personalizzato

public class FutureDateAttribute : ValidationAttribute 
    { 
     public override bool IsValid(object value) 
     { 
      if (value == null|| (DateTime)value < DateTime.Now) 
       return false; 

      return true; 
     } 

    } 

Come posso ottenere questo lavoro sul lato client anche con jQuery?

risposta

161

Ecco come procedere:

Inizia definendo l'attributo di convalida personalizzato:

public class FutureDateAttribute : ValidationAttribute, IClientValidatable 
{ 
    public override bool IsValid(object value) 
    { 
     if (value == null || (DateTime)value < DateTime.Now) 
      return false; 

     return true; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     yield return new ModelClientValidationRule 
     { 
      ErrorMessage = this.ErrorMessage, 
      ValidationType = "futuredate" 
     }; 
    } 
} 

Notate come implementa IClientValidatable. Successivo scriviamo il nostro modello:

public class MyViewModel 
{ 
    [FutureDate(ErrorMessage = "Should be in the future")] 
    public DateTime Date { get; set; } 
} 

Poi un controller:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      // intentionally put in the past 
      Date = DateTime.Now.AddDays(-1) 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

e, infine, una visione:

@using (Html.BeginForm()) 
{ 
    @Html.LabelFor(x => x.Date) 
    @Html.TextBoxFor(x => x.Date) 
    @Html.ValidationMessageFor(x => x.Date) 
    <input type="submit" value="OK" /> 
} 

L'ultima parte della magia che accada è quello di definire l'adattatore personalizzato :

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 
<script type="text/javascript"> 
    // we add a custom jquery validation method 
    jQuery.validator.addMethod('greaterThan', function (value, element, params) { 
     if (!/Invalid|NaN/.test(new Date(value))) { 
      return new Date(value) > new Date($(params).val()); 
     } 
     return isNaN(value) && isNaN($(params).val()) || (parseFloat(value) > parseFloat($(params).val())); 
    }, ''); 

    // and an unobtrusive adapter 
    jQuery.validator.unobtrusive.adapters.add('futuredate', { }, function (options) { 
     options.rules['greaterThan'] = true; 
     options.messages['greaterThan'] = options.message; 
    }); 
</script> 
+3

Risposta brillante! – raklos

+0

Quasi funzionante: in quale formato deve essere inserita la data? – raklos

+1

@raklos, che dipenderà dalle impostazioni di localizzazione del browser e del server. In caso di differenze le cose si complicano in quanto un formato può superare la convalida del client ma non la convalida del server e viceversa. Inoltre, spetta a te decidere in che formato vuoi che siano le tue date. –

4

Ha richiesto un po 'di tempo dal momento che la tua domanda è stato chiesto, ma se vi piace ancora i metadati, e tu sei ancora aperti per le alternative semplificate, è possibile risolvere il problema utilizzando seguenti annotazioni:

[Required] 
[AssertThat("Date > Now()")] 
public DateTime? Date { get; set; } 

Funziona per entrambi - server e client, fuori dalla scatola. Per ulteriori dettagli, consulta la libreria ExpressiveAnnotations.

+0

Hai salvato la giornata con la tua biblioteca. Così semplice nell'uso e molto utile. Grazie – Maco

Problemi correlati