C # Невозможно найти другие свойства в пользовательском атрибуте проверки - PullRequest
0 голосов
/ 26 сентября 2018

Попытка создать собственный атрибут проверки, который использует имя свойства для поиска другого свойства.

В настоящее время у меня возникают проблемы с поиском другого свойства.Кажется, я не могу найти это свойство (или вообще какие-либо свойства).

Проверка на 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");
    }

Iценим тот факт, что пользовательский атрибут проверки в настоящий момент ничего не делает, но это потому, что я застрял в этой проблеме.

Спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Давайте используем следующий фрагмент кода, чтобы объяснить, что здесь происходит:

protected override ValidationResult IsValid(object value, ValidationContext ctx)
{
    var typeFullName = ctx.ObjectInstance.GetType().FullName;

    ...
}

В этом примере вы можете ожидать, что typeFullName будет XXX.OrganisationDetailsModel, но это не такt : на самом деле 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 типа InputModel, которое связывается с помощью [BindProperty].
  • Удалено [BindProperty] из исходных свойств, которые теперь были перемещены.

Последний шаг - заменить любое использование, например, CompanyNumber на Input.CompanyNumber в PageModel в соответствующем .cshtml и убедиться, что вы используете префикс Input. при доступе к свойствам.внутри самого класса PageModel.

0 голосов
/ 26 сентября 2018

По док.getProperties () возвращает только публичные.

https://docs.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=netframework-4.7.2

Так что если хотите получить непубличные свойства.Найти ниже:

Получить значение защищенного свойства базового класса, используя отражения


protected override ValidationResult IsValid(object value, ValidationContext context) {
    var property = context.ObjectType.getProperty(context.MemberName);

    // TODO

    return ValidationResult.Success;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...