C# 基于其他属性更改正则表达式和错误消息
在下面的分部类中,我有一个属性Amount和一个RegularExpression属性。这是因为它将字段中的值限制为小数点后2位。但是,“金额”字段有多个位置,小数位数因使用位置而异。CategoryId确定要显示的小数位数。是否有方法基于类CategoryId中的另一个属性更改小数位数限制和ErrorMessage 下面是部分类:C# 基于其他属性更改正则表达式和错误消息,c#,asp.net-mvc,C#,Asp.net Mvc,在下面的分部类中,我有一个属性Amount和一个RegularExpression属性。这是因为它将字段中的值限制为小数点后2位。但是,“金额”字段有多个位置,小数位数因使用位置而异。CategoryId确定要显示的小数位数。是否有方法基于类CategoryId中的另一个属性更改小数位数限制和ErrorMessage 下面是部分类: [MetadataType(typeof(CS_Parameter_Statewide_AllGrades_ScenarioMetaData))] public p
[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]
[RegularExpression(@"^\d+.\d{0,2}$", ErrorMessage = "Price can't have more than 2 decimal places")]
public double Amount { get; set; }
}
}
以下是视图中显示金额值的循环。如果您查看,您可以看到显示格式将因使用格式方法而有所不同。Format方法返回一个字符串,该字符串确定“TextBoxFor”重载中的格式
@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, Model.Format(Model.AllGradesParamList[i].Amount, Model.AllGradesParamList[i].CategoryId))
@Html.ValidationMessageFor(x => Model.AllGradesParamList[i].Amount)
</td>
</tr>
}
我不确定是否需要编写自定义属性。但是如果我这样做了,有人能提供一个简单但完整的例子,它将像我上面描述的那样工作。有几个选项;正如您所建议的,您可以编写自己的ValidationAttribute,可能来自RegularExpressionAttribute类等等。实现IValidatableObject接口以进行更复杂的验证可能是一个可行的选择。下面是一个简单的例子:
public class Awesome : IValidatableObject {
[Required]
public Int32 Id { get; set; }
public String Whatever { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
// Perform validation checks...
// If 'valid' return <null>,
// and if not, populate the ValidationResult list and return that.
// The validationContext.ObjectInstance contains what you need, if you
// cast it properly (see my next example).
}
}
在MyValidator中,您可以访问Id属性,如下所示:
public class MyValidator {
public static ValidationResult ValidateThis(String value, ValidationContext context) {
var awesome = context.ObjectInstance as Awesome;
if(awesome == null)
throw new InstanceNotFoundException(
"This validator only works with an Awesome instance.");
var id = awesome.Id;
// Do your thing here, like run a dynamic regular expression match
// based on the value of 'id'.
return ValidationResult.Success;
}
}
对我来说,这段代码并不完美——我不喜欢它假设ObjectInstance是一种特定类型(可能是上下文)。ObjectInstance as IAwesome稍微好一点,所以我可能不建议使用它,但它确实存在
另一方面,不要忘了查看IClientValidable或为自定义验证解决方案添加客户端验证的内容。我想,如果您创建自己的ValidationAttribute,您可能迟早会想实现它。让它拥有尽可能多的小数,然后添加一个方法以输出x小数,这不是更容易吗?是的,但我试图限制用户的输入实际上IClientValidable部分是我最难处理的部分。你能把它包括在你的答案中吗?也许你可以看看类似的东西。如果你遇到了麻烦,发布一个关于这个问题和你尝试过的解决方案的新问题;
public class MyValidator {
public static ValidationResult ValidateThis(String value, ValidationContext context) {
var awesome = context.ObjectInstance as Awesome;
if(awesome == null)
throw new InstanceNotFoundException(
"This validator only works with an Awesome instance.");
var id = awesome.Id;
// Do your thing here, like run a dynamic regular expression match
// based on the value of 'id'.
return ValidationResult.Success;
}
}