基于id的自定义错误消息

时间:2014-12-03 04:07:02

标签: c# asp.net-mvc

我使用for循环显示html表中表的记录。在每一行中,Amount值的格式不同 - 有些将具有4个小数位,大约3个小数位,有些将是货币。如果您查看textbox for部分,您还会看到我使用Format方法根据CategoryId格式化数据。

此外,某些Amount是百分比,需要进行验证才能确定它们是否小于1。问题是它们都使用相同的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]属性不同,无效值将发送到post。如何阻止值发布并在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 } };
    }

}

1 个答案:

答案 0 :(得分: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?