2014-12-03 2 views
0

Я показываю записи из таблицы в таблице html, используя цикл for. В каждой строке значение Amount будет отличаться в формате - у некоторых будет 4 десятичных знака, около 3 знаков после запятой, а некоторые будут валютой. Если вы посмотрите на часть textboxfor, вы также увидите, что я использую метод Format для форматирования данных на основе CategoryId.Пользовательское сообщение об ошибке на основе идентификатора

Кроме того, некоторые из Amount s являются процентами и нуждаются в проверке, чтобы убедиться, что они меньше единицы. Проблема в том, что все они используют одно и то же свойство Amount, поэтому просто украшать атрибутом Validation сложно.

У меня не возникло проблем с использованием атрибута [Required] (см. Ниже). Однако я не уверен, как подтвердить проценты. Есть ли способ, которым я мог бы использовать CategoryId для создания пользовательского сообщения об ошибке, которое будет видно в ValidationMessageFor?

@for (int i = 0; i < Model.AllGradesParamList.Count; i++) 
{ 
    <tr> 
     <td> 
      @Model.CategoryList.Where(x => x.Id == Model.AllGradesParamList[i].CategoryId).Select(x => x.Name).FirstOrDefault() 
      @Html.HiddenFor(model => Model.AllGradesParamList[i].CategoryId) 
     </td> 
     <td> 
      @Html.TextBoxFor(x => Model.AllGradesParamList[i].Amount, new { @Value = Model.Format(Model.AllGradesParamList[i].Amount, Model.AllGradesParamList[i].CategoryId) }) 
      @Html.ValidationMessageFor(x => Model.AllGradesParamList[i].Amount) 
     </td> 
    </tr> 
} 

Частичный класс (остальная часть класса автоматически генерируется, в том числе CategoryId):

[MetadataType(typeof(CS_Parameter_Statewide_AllGrades_ScenarioMetaData))] 
public partial class CS_Parameter_Statewide_AllGrades_Scenario 
{ 
    public int Category { get; set; } 

    public class CS_Parameter_Statewide_AllGrades_ScenarioMetaData 
    { 
     [Required] 
     [ValidAmountAttribute("CategoryId")] 
     public double Amount { get; set; } 
    } 

} 

Редактировать: Я также начал создавать этот пользовательский атрибут, но он не работает так, как я хочу. В отличие от атрибута [Required], недопустимые значения отправляются на почту. Как я могу предотвратить публикацию значений и отображать ошибки в ValidationMessageFor?

*** Редактировать: Моя попытка внедрения IClientValidatable не работает. На стороне сервера я звоню ModelState.IsValid, и это работает, но оно не должно даже заходить так далеко. Должен ли я писать дополнительный Javascript, чтобы заставить его работать? Может, некоторые используют jQuery.validator.unobtrusive.adapters.add()?

public class ValidAmountAttribute : ValidationAttribute, IClientValidatable // IClientValidatable for client side Validation 
{ 
    private readonly string _categoryId; 
    public ValidAmountAttribute(string categoryId) 
    { 
     _categoryId = categoryId; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var catId = validationContext.ObjectType.GetProperty(_categoryId).GetValue(validationContext.ObjectInstance, null); 

     var amountProperty = validationContext.ObjectType.GetProperty("Amount"); 

     double amountValue = (double)amountProperty.GetValue(validationContext.ObjectInstance, null); 

     if ((catId == 212 || catId == 213) && amountValue > 1) 
     { 
      return new ValidationResult("Amount is not valid"); 
     } 
     return ValidationResult.Success; 
    } 

    // Implement IClientValidatable for client side Validation 
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     return new ModelClientValidationRule[] { new ModelClientValidationRule { ValidationType = "textbox", ErrorMessage = this.ErrorMessage } }; 
    } 

} 
+0

Примечание: вы должны использовать перегрузку 'TextBoxFor()', которая принимает строку формата, не пытаясь установить атрибут 'value' –

+0

Похоже, вы действительно должны использовать представление модель, которая обладает свойствами, которые вы хотите отображать/редактировать и проверять. –

+0

'Amount' - это свойство, которое я хочу отобразить. У него просто разные способы его форматирования и проверки. К сожалению, это продиктовано таблицей db. 'Amount' - столбец в таблице – navig8tr

ответ

0

Вы можете создать собственный собственный атрибут собственной аттестации.

public class ValidAmount : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     string[] memberNames = { "Amount" }; 
     var amountProperty = validationContext.ObjectType.GetProperty("Amount"); 

     double amountValue = (double)amountProperty.GetValue(validationContext.ObjectInstance, null); 

     // at this stage you have "amount value" 
     // here you are verifying whether amount is less than 1 
     if (amountValue<1) 
     { 
      // here you return your custom error message 
      return new ValidationResult("Amount is not valid",memberNames); 
     } 

     return ValidationResult.Success; 
    } 
} 

Примените свой собственный атрибут проверки к свойству model/viewmodel. Например:

[ValidAmount] 
    public double Amount { get; set; } 

Вы также можете проверить два свойства в одном классе атрибутов проверки. Следуйте по этой ссылке для этого: How to create a custom validation attribute?

+0

Будет ли отображаться сообщение об ошибке в 'ValidationMessageFor'? – navig8tr

+0

Да, это отобразит ValidationMessageFor, поскольку другой встроенный атрибут проверки –

+0

Сообщите мне, если вам нужно использовать CategoryId в этой логике Validation ValidAmount, и вы не можете это сделать –

Смежные вопросы