C#无法在自定义验证属性中找到其他属性 [英] C# Unable to find other properties in custom validation attribute

查看:120
本文介绍了C#无法在自定义验证属性中找到其他属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试创建自己的验证属性,该属性使用属性名称查找另一个属性。

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).

属性== 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 显然没有名为的属性。 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.

在很多情况下,在上多次使用 [BindProperty] PageModel 。当然有可能,但是似乎每个属性都被视为单个属性,并且 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 type InputModel, that gets bound using [BindProperty].
  • Removed [BindProperty] from the original properties that have now been moved.

最后一步是替换所有用法,例如 CompanyNumber PageModel 对应的 Input.CompanyNumber .cshtml ,并确保在访问 PageModel <中的属性时使用前缀 Input。 / code>类本身。

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#无法在自定义验证属性中找到其他属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆