Я показываю записи из таблицы в таблице 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 } };
}
}
Примечание: вы должны использовать перегрузку 'TextBoxFor()', которая принимает строку формата, не пытаясь установить атрибут 'value' –
Похоже, вы действительно должны использовать представление модель, которая обладает свойствами, которые вы хотите отображать/редактировать и проверять. –
'Amount' - это свойство, которое я хочу отобразить. У него просто разные способы его форматирования и проверки. К сожалению, это продиктовано таблицей db. 'Amount' - столбец в таблице – navig8tr