11

chiedo domanda simile here ma in questa domanda io uso un'altra applicazione, esattamente this way i seguenti codici mostrano i miei implementazioni:ASP.NET MVC implementare l'uso di convalida personalizzata IClientValidatable

Modello:

public class Department { 

    public long Id { get; set; } 

    [IsDateAfter("Date2", true, ErrorMessage = "O My")] 
    public DateTime Date1 { get; set; } 
    public DateTime Date2 { get; set; } 
    public string Name1 { get; set; } 
    public string Name2 { get; set; } 

} 

personalizzata Validator:

public sealed class IsDateAfter : ValidationAttribute, IClientValidatable { 

    private readonly string testedPropertyName; 
    private readonly bool allowEqualDates; 

    public IsDateAfter(string testedPropertyName, bool allowEqualDates = false) 
    { 
     this.testedPropertyName = testedPropertyName; 
     this.allowEqualDates = allowEqualDates; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext 
validationContext) { 
     var propertyTestedInfo = 
validationContext.ObjectType.GetProperty(this.testedPropertyName); 
     if (propertyTestedInfo == null) { 
      return new ValidationResult(string.Format("unknown property 
{0}", this.testedPropertyName)); 
     } 

     var propertyTestedValue = 
propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); 

     if (value == null || !(value is DateTime)) { 
      return ValidationResult.Success; 
     } 

     if (propertyTestedValue == null || !(propertyTestedValue is 
DateTime)) { 
      return ValidationResult.Success; 
     } 

     // Compare values 
     if ((DateTime)value >= (DateTime)propertyTestedValue) { 
      if (this.allowEqualDates) { 
       return ValidationResult.Success; 
      } 
      if ((DateTime)value > (DateTime)propertyTestedValue) { 
       return ValidationResult.Success; 
      } 
     } 

     return new 
ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
    } 

    public IEnumerable<ModelClientValidationRule> 
GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { 
     var rule = new ModelClientValidationRule { 
      ErrorMessage = this.ErrorMessageString, 
      ValidationType = "isdateafter" 
     }; 
     rule.ValidationParameters["propertytested"] = 
this.testedPropertyName; 
     rule.ValidationParameters["allowequaldates"] = 
this.allowEqualDates; 
     yield return rule; 
    } 
} 

Script:

$.validator.unobtrusive.adapters.add(
'isdateafter', ['propertytested', 'allowequaldates'], function (options) { 
    options.rules['isdateafter'] = options.params; 
    options.messages['isdateafter'] = options.message; 
}); 
$.validator.addMethod("isdateafter", function (value, element, params) { 
alert(params.propertytested); 
var startdatevalue = $('input[name="' + params.propertytested + '"]').val(); 
if (!value || !startdatevalue) return true; 
return (params.allowequaldates) ? Date.parse(startdatevalue) <= Date.parse(value) : 
Date.parse(startdatevalue) < Date.parse(value); 
}, ''); 

e la mia pagina _Layout (Pagina master)

<!DOCTYPE html> 
<html> 
<head> 
<title>@ViewBag.Title</title> 
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" 
type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" 
type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" 
type="text/javascript"></script> 
</head> 
<body> 
<div class="page"> 
    <div id="header"> 
     <div id="title"> 
      <h1> 
       My MVC Application</h1> 
     </div> 
     <div id="logindisplay"> 
      @Html.Partial("_LogOnPartial") 
     </div> 
     <div id="menucontainer"> 
      <ul id="menu"> 
     <li>@Html.ActionLink("Departments", "Index", "Department")</li> 
      </ul> 
     </div> 
    </div> 
    <div id="main"> 
     @RenderBody() 
    </div> 
    <div id="footer"> 
    </div> 
</div> 
</body> 
</html> 

naturalmente a modificare e creare Visualizzare le pagine l'altra fonte di script sono i seguenti:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" 
type="text/javascript"></script> 

Una parte di Crea Dom pagina:

<fieldset> 
<legend>Department</legend> 
<div class="editor-label"> 
<label for="Date1">Date1</label> 
</div> 
<div class="editor-field"> 
<input id="Date1" class="text-box single-line valid" type="text" value="" name="Date1" 
data-val-required="The Date1 field is required." data-val-isdateafter- 
propertytested="Date2" data-val-isdateafter-allowequaldates="False" data-val- 
isdateafter="O My" data-val="true"> 
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg- 
    for="Date1"></span> 
</div> 
<div class="editor-label"> 
<label for="Date2">Date2</label> 
</div> 
<div class="editor-field"> 
<input id="Date2" class="text-box single-line valid" type="text" value="" name="Date2" 
data-val-required="The Date2 field is required." data-val="true"> 
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg- 
for="Date2"></span> 
</div> 

provo Tutto dell'attuazione essere lo stesso di here, ma che non funziona in lato client e la necessità di postback, non ho qualsiasi altra applicazione, ad esempio registrare in global.asax come this, Does qualcuno lo sa? Ho davvero confuso, ho provato in 2 modi ma nessuno di loro ha dato la vera risposta.

risposta

9

Hai incasinato le inclusioni di script. Nella tua _Layout aver incluso i seguenti script in questo ordine:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script> 

Ora, ovviamente jquery.validate.min.js e jquery.validate.js rappresenta lo stesso copione, il primo è la versione minified. Ma dal momento che non hai incluso lo script jquery.validate.unobtrusive.js (questo è fatto molto più tardi nella tua vista), lo script personalizzato jQuery.IsDateAfter.js conterrà errori poiché non sarà a conoscenza dell'oggetto $.validator.unobtrusive.adapters che stai utilizzando. Quindi, ecco come gli script nel layout dovrebbe guardare:

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

Si potrebbe anche aggiungere la tua jQuery.IsDateAfter.js script personalizzato al layout, alla fine, se lo si desidera nel caso in cui è utilizzato in molti punti di vista, e se non si poteva aggiungerlo alla vista:

<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script> 

che è l'unica sceneggiatura si dovrebbe avere nella vista. Dovresti rimuovere tutte le altre inclusioni di script jquery.* dalle tue pagine Modifica e Crea vista.

Nota: si noterà anche che ho rimosso tutti gli script Microsoft*.js dal proprio layout. Sono obsoleti e non dovrebbero più essere utilizzati in ASP.NET MVC 3.

+2

Ho seguito questo e posso vedere i messaggi di errore di convalida mentre modifico il modulo che è grande. Una cosa strana a riguardo, che non smette di postare anche se ha campi non validi con i messaggi di errore di validazione corretti, tuttavia il server riconosce ModelState.IsValid come falso ... è un comportamento normale o mi manca qualcosa? – afr0

Problemi correlati