2012-07-22 46 views
2

這是簡化的模型:ASP.NET MVC自定義客戶端日期驗證,如何獲取輸入名稱?

public class Person { 
    public int Id; 
    public string Name; 
} 

public class Task { 
    public int Id; 
    public int PersonId; 
    public DateTime StartDate; 
    [GreaterThan("StartDate")] 
    public DateTime EndDate; 
} 

爲了驗證結束日期> =起始日期,我寫一般GreaterThanAttribute。服務器端是微不足道的,但我有客戶端驗證問題。

My GreaterThanAttribute從構造函數中獲得了其他屬性(例如:「StartDate」),然後我將這個其他屬性名稱作爲驗證規則傳遞給javascript。但它不起作用,因爲JS不會找到這個元素,因爲MVC將會把&命名爲「Task.StartDate」,而不是「StartDate」。

我的問題是,我怎麼能得到控制器使用的IClientValidatable.GetClientValidationRules()內的模型的前綴?

謝謝

回答

2

這裏是你如何可以實現它:

public class GreaterThanAttribute : ValidationAttribute, IClientValidatable 
{ 
    private readonly string _otherProperty; 
    public GreaterThanAttribute(string otherProperty) 
    { 
     _otherProperty = otherProperty; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, _otherProperty); 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var property = validationContext.ObjectType.GetProperty(_otherProperty); 
     if (property == null) 
     { 
      return new ValidationResult(
       string.Format(
        CultureInfo.CurrentCulture, 
        "unknown property {0}", 
        _otherProperty 
       ) 
      ); 
     } 
     var otherValue = (DateTime)property.GetValue(validationContext.ObjectInstance, null); 
     var thisValue = (DateTime)value; 
     if (thisValue <= otherValue) 
     { 
      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
     } 

     return null; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationRule(); 
     rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); 
     rule.ValidationType = "greaterthandate"; 
     rule.ValidationParameters["other"] = "*." + _otherProperty; 
     yield return rule; 
    } 
} 

,並在客戶端:

(function ($) { 
    var getModelPrefix = function (fieldName) { 
     return fieldName.substr(0, fieldName.lastIndexOf('.') + 1); 
    }; 

    var appendModelPrefix = function (value, prefix) { 
     if (value.indexOf('*.') === 0) { 
      value = value.replace('*.', prefix); 
     } 
     return value; 
    }; 

    $.validator.unobtrusive.adapters.add('greaterthandate', ['other'], function (options) { 
     var prefix = getModelPrefix(options.element.name), 
      other = options.params.other, 
      fullOtherName = appendModelPrefix(other, prefix), 
      element = $(options.form).find(':input[name=' + fullOtherName + ']')[0]; 

     options.rules['greaterThanDate'] = element; 
     if (options.message) { 
      options.messages['greaterThanDate'] = options.message; 
     } 
    }); 

    $.validator.addMethod('greaterThanDate', function (value, element, params) { 
     var otherDate = $(params).val(); 
     var thisDate = value; 

     // TODO: put your custom date comparison implementation here between 
     // the 2 values. Be careful here. Javascript date handling is culture dependent 
     // so you might need to account for that when building your js Date instances 

     return false; 
    }, ''); 
})(jQuery); 
+0

完美,這就是我需要的,食譜是函數「getModelPrefix」,我有前綴,謝謝Darin – bdnt 2012-07-22 07:26:05

0

這已經完成。我建議你使用FoolProof驗證。如果你不想,你至少可以看看他們的soure代碼。這裏有一個link

+0

我知道萬無一失,它不適合MVC3工作,IsValid的尚未實現,這就是爲什麼我必須寫我的自我。而且,萬無一失,不會在客戶端處理自定義日期格式,例如「DD.MM.YYYY」格式,因爲萬無一失依賴於Date.parse()。 – bdnt 2012-07-22 07:13:09

相關問題