问题描述
尝试制作我自己的验证属性,该属性使用属性名称来查找另一个属性.
Trying to make my own Validation Attribute that uses a property name to find another property.
目前,我在查找其他属性时遇到问题.我似乎无法找到此属性(或实际上找不到任何属性).
Currently, I am having problems finding the other property. It seems I am unable to find this property (or in fact any properties).
property == null
的检查总是为真.
为什么我无法找到属性的任何想法?
Any ideas why I wouldn't be able to find properties?
这是我制作的自定义过滤器
This is the custom filter I have made
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);
}
这是我在剃刀视图后面使用的模型.
This is the model I am using behind my razor view.
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");
}
我很感激自定义验证属性目前并没有真正做任何事情,但那是因为我一直被这个问题困住了.
I appreciate the fact that the custom validation attribute doesn't really do anything at the moment but that is becuase I have become stuck on this issue.
感谢您的帮助.
推荐答案
让我们使用以下代码片段来帮助解释这里发生的事情:
Let's use the following code snippet to help explain what is going on here:
protected override ValidationResult IsValid(object value, ValidationContext ctx)
{
var typeFullName = ctx.ObjectInstance.GetType().FullName;
...
}
在这个例子中,你可能希望 typeFullName
是 XXX.OrganisationDetailsModel
,但 它不是:它实际上是 System.String
(您要验证的属性 的类型).System.String
显然没有名为 e.g. 的属性.CompanyHouseToggle
等 GetProperty
正确返回 null
.
In this example, you might expect typeFullName
to be XXX.OrganisationDetailsModel
, but it isn't: it's actually System.String
(the type of the property you’re trying to validate). System.String
clearly does not have a property named e.g. CompanyHouseToggle
and so GetProperty
rightly returns null
.
我还没有见过在 PageModel
上多次使用 [BindProperty]
的情况.这当然是可能的,但似乎每个属性都被视为单独的,并且 PageModel
本身没有被验证.
I've not seen many cases where [BindProperty]
has been used more than once on a PageModel
. It's certainly possible, but it appears that each property is treated as being individual and that the PageModel
itself is not being validated.
为了解决这个问题,您可以将单独的属性转换为复杂类型并使用它.文档和示例在 PageModel
类内部为此使用了一个内联类.以下是更新后的 OrganisationDetailsModel
类的示例:
In order to work around this, you can just turn your individual properties into a complex type and use that instead. The docs and examples use an inline class for this, inside of the PageModel
class. Here's an example of an updated OrganisationDetailsModel
class:
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
的所有其他属性. - 添加类型为
InputModel
的Input
属性,使用[BindProperty]
绑定. - 从现在已移动的原始属性中删除了
[BindProperty]
.
- Creation of an
InputModel
class to hold all properties. - Removal of all other properties that have now moved into
InputModel
. - Addition of an
Input
property of typeInputModel
, that gets bound using[BindProperty]
. - Removed
[BindProperty]
from the original properties that have now been moved.
最后一步是替换任何用法,例如CompanyNumber
与 PageModel
对应的 .cshtml
中的 Input.CompanyNumber
并确保您使用 访问
前缀.PageModel
类本身中的属性时输入.
The last step is to replace any usage of e.g. CompanyNumber
with Input.CompanyNumber
in the PageModel
's corresponding .cshtml
and to ensure you use the Input.
prefix when accessing properties within the PageModel
class itself.
这篇关于C# 无法在自定义验证属性中找到其他属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!