2011-01-20 13 views

Odpowiedz

161

Oto jak postępować:

Zacznij od zdefiniowania atrybutu walidacji niestandardowej:

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" 
     }; 
    } 
} 

Wskazówki jak realizuje IClientValidatable. Następny piszemy nasz model:

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

Następnie kontroler:

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); 
    } 
} 

i wreszcie widok:

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

Ostatnia część dla magii zdarzyć, aby określić kartę niestandardową :

<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

Znakomita odpowiedź! – raklos

+0

Prawie działa - w jakim formacie powinna być data? – raklos

+1

@raklos, zależy to od ustawień lokalizacji przeglądarki i serwera. Jeśli masz różnice, rzeczy stają się skomplikowane, ponieważ jeden format może przekazać sprawdzanie poprawności klienta, ale nie sprawdzanie poprawności serwera i na odwrót. Od Ciebie zależy także, w jakim formacie chcesz datować. –

4

Zajęło trochę czasu od Twojego pytano, ale jeśli nadal jak metadane, a ty wciąż otwarta dla uproszczonych rozwiązań alternatywnych, można rozwiązać problemu przy użyciu następujących adnotacji:

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

Działa zarówno - serwera i klienta, po wyjęciu z pudełka. Aby uzyskać więcej informacji, zapoznaj się z biblioteką ExpressiveAnnotations.

+0

Zapisałeś mój dzień w bibliotece. Tak prosty w użyciu i bardzo przydatny. Dzięki – Maco

Powiązane problemy