尝试创建自己的验证属性,该属性使用属性名称查找另一个属性。
目前,我在寻找其他财产方面遇到问题。看来我找不到此属性(或实际上任何属性)。
对property == null
的检查总是正确的。
我为什么找不到属性的任何想法?
这是我制作的自定义过滤器
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectInstance.GetType().GetProperty(PropertyName);
if (property == null)
{
return new ValidationResult(string.Format(
"Unknown property {0}",
new[] { PropertyName }
));
}
var propertyValue = property.GetValue(validationContext.ObjectInstance);
// Just for testing purposes.
return new ValidationResult(ErrorMessage);
}
这是我在剃刀视图后面使用的模型。
public class OrganisationDetailsModel : PageModel
{
private readonly FormStateContext _context;
public OrganisationDetailsModel(FormStateContext context)
{
_context = context;
}
[BindProperty]
[RegularExpression(pattern: "(yes|no)")]
[Required(ErrorMessage = "Please select if you are registered on companies house")]
public string CompanyHouseToggle { get; set; }
[BindProperty]
[StringLength(60, MinimumLength = 3)]
[RequiredIf("CompanyHouseToggle")]
public string CompanyNumber { get; set; }
[BindProperty]
[StringLength(60, MinimumLength = 3)]
[Required(ErrorMessage = "Enter your organisation name")]
public string OrganisationName { get; set; }
[BindProperty]
[RegularExpression(pattern: "(GB)?([0-9]{9}([0-9]{3})?|[A-Z]{2}[0-9]{3})", ErrorMessage = "This VAT number is not recognised")]
[Required(ErrorMessage = "Enter your vat number")]
public string VatNumber { get; set; }
public void OnGet()
{
}
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("ApplicantDetails");
}
我很欣赏以下事实:自定义验证属性目前并没有真正做任何事情,但这是因为我一直陷在这个问题上。
感谢您的帮助。
答案 0 :(得分:0)
通过文档。 getProperties()仅返回公众。
https://docs.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=netframework-4.7.2
因此,如果要获取非公共属性。在下面找到。
Get protected property value of base class using reflections
protected override ValidationResult IsValid(object value, ValidationContext context) {
var property = context.ObjectType.getProperty(context.MemberName);
// TODO
return ValidationResult.Success;
}
答案 1 :(得分:0)
让我们使用以下代码段来帮助解释这里发生的事情:
protected override ValidationResult IsValid(object value, ValidationContext ctx)
{
var typeFullName = ctx.ObjectInstance.GetType().FullName;
...
}
在此示例中,您可能期望typeFullName
为XXX.OrganisationDetailsModel
,但并非:实际上是System.String
(您要验证的属性。 System.String
显然没有名为的属性。 CompanyHouseToggle
,因此GetProperty
正确地返回了null
。
我还没有看到在[BindProperty]
上多次使用PageModel
的情况。当然可以,但是似乎每个属性都被视为单个属性,PageModel
本身并未得到验证。
要解决此问题,您只需将单个属性转换为复杂类型并使用它即可。在PageModel
类内部,文档和示例为此使用了一个内联类。这是更新后的OrganisationDetailsModel
类的示例:
public class OrganisationDetailsModel : PageModel
{
...
[BindProperty]
public InputModel Input { get; set; }
public void OnGet() { }
public IActionResult OnPost()
{
if (!ModelState.IsValid)
return Page();
return RedirectToPage("ApplicantDetails");
}
public class InputModel
{
[RegularExpression(pattern: "(yes|no)")]
[Required(ErrorMessage = "Please select if you are registered on companies house")]
public string CompanyHouseToggle { get; set; }
[StringLength(60, MinimumLength = 3)]
[RequiredIf("CompanyHouseToggle")]
public string CompanyNumber { get; set; }
...
}
}
这包括以下更改:
InputModel
类以容纳所有属性。InputModel
的所有其他属性。Input
的{{1}}属性,该属性使用InputModel
进行绑定。[BindProperty]
。 最后一步是替换任何用法,例如{{1}中对应的[BindProperty]
中的CompanyNumber
和Input.CompanyNumber
,并确保在访问PageModel
类本身内的属性时使用.cshtml
前缀