Проверка Уровня класса/Модели (в противоположность Уровню Свойства)? (ASP.NET MVC 2.0)

В основном, что говорит заголовок. У меня есть несколько свойств, которые объединяются вместе для реального создания одного логического ответа, и я хотел бы выполнить код доступа серверной стороны (что я пишу), которые принимают во внимание эти несколько полей и рычага только до одного вывода/сообщения об ошибке проверки, который пользователи видят на веб-странице.

Я посмотрел на scott guthries метод расширения атрибута и использования его в Ваших dataannotations объявлениях, но, как я вижу, нет никакого способа объявить dataannotations-атрибут-стиля на нескольких свойствах, и можно только поместить объявления (такие как [электронная почта], [Диапазон], [Необходимый]) по одному свойству :(

я посмотрел на PropertiesMustMatchAttribute в проекте mvc 2.0 по умолчанию, который появляется, когда Вы запускаете новый проект, этот пример так же полезен как использование пары контактов для проверки машинного масла - бесполезный!

я попробовал этот метод, однако, создав атрибут уровня класса, и понятия не имею, как отобразить ошибку от этого на моей aspx странице. я попробовал HTML. ValidationMessage ("ClassNameWhereAttributeIsAdded") и множество других вещей, и это не работало. и я должен упомянуть, нет ОДНОГО сообщения в блоге при выполнении проверки на этом уровне - несмотря на этот являющийся общей потребностью ни в каком проекте или сценарии бизнес-логики!

кто-либо может помочь мне в отображении моего сообщения на моей aspx странице, и также если возможный надлежащий документ или ссылочная проверка объяснения на этом уровне?

15
задан Erx_VB.NExT.Coder 11 May 2012 в 21:36
поделиться

4 ответа

Теперь, когда вы просмотрели аннотации данных и пришли к выводу, что они не адаптированный к вашему сценарию, я бы посоветовал вам взглянуть на FluentValidation , его интеграцию с ASP.NET MVC и то, как вы модульное тестирование своей логики проверки - вы выиграли Не расстраивайтесь (я действительно ничего не имею против аннотаций к данным, они отлично подходят для постов в блогах и руководств, но как только вы столкнетесь с реальными приложениями, вы быстро поймете ограничения).


ОБНОВЛЕНИЕ:

В соответствии с просьбой в разделе комментариев вот пример использования инфраструктуры FluentValidation с одной серверной функцией проверки, имеющей доступ к нескольким свойствам (пожалуйста, не делайте этого, так как это некрасиво и есть способ получше):

class AuthInfo
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}

class AuthInfoValidator : AbstractValidator<AuthInfo>
{
    public override ValidationResult Validate(AuthInfo instance)
    {
        var result = base.Validate(instance);
        if (string.IsNullOrEmpty(instance.Username))
        {
            result.Errors.Add(new ValidationFailure("Username", "Username is required"));
        }
        if (string.IsNullOrEmpty(instance.Password))
        {
            result.Errors.Add(new ValidationFailure("Password", "Password is required"));
        }
        if (string.IsNullOrEmpty(instance.ConfirmPassword))
        {
            result.Errors.Add(new ValidationFailure("ConfirmPassword", "ConfirmPassword is required"));
        }
        if (instance.Password != instance.ConfirmPassword)
        {
            result.Errors.Add(new ValidationFailure("ConfirmPassword", "Passwords must match"));
        }
        return result;
    }
}

Более естественный способ сделать это следующий (он также невосприимчив к переименованию свойств, поскольку не содержит магических строк):

class AuthInfoValidator : AbstractValidator<AuthInfo>
{
    public AuthInfoValidator()
    {
        RuleFor(x => x.Username)
            .NotEmpty()
            .WithMessage("Username is required");

        RuleFor(x => x.Password)
            .NotEmpty()
            .WithMessage("Password is required");

        RuleFor(x => x.ConfirmPassword)
            .NotEmpty()
            .WithMessage("ConfirmPassword is required");

        RuleFor(x => x.ConfirmPassword)
            .Equal(x => x.Password)
            .WithMessage("Passwords must match");
    }
}
14
ответ дан 1 December 2019 в 02:55
поделиться

Я не уверен, но это вы продолжаете голосовать за мои ответы/вопросы без видимых причин (или из-за моих взглядов на VB.NET)?

В любом случае, PropertiesMustMatchAttribute - это просто хорошая реализация использования значений определенного свойства объекта. Если вам нужно выполнить некоторую логику, используя несколько полей объекта, вы можете сделать это следующим образом, аналогично тому, что делает PropertiesMustMatchAttribute.

Ниже приведена основная часть ValidationAttribute, которая обращается к свойствам объекта для выполнения некоторой логики.

    public override bool IsValid(object value)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);

        // Get the values of the properties we need. 
        // Alternatively, we don't need to hard code the property names,
        // and instead define them via the attribute constructor
        object prop1Value = properties.Find("Person", true).GetValue(value);
        object prop2Value = properties.Find("City", true).GetValue(value);
        object prop3Value = properties.Find("Country", true).GetValue(value);

        // We can cast the values we received to anything
        Person person = (Person)prop1value; 
        City city = (City)prop2value;
        Country country = (Country)prop3value;

        // Now we can manipulate the values, running any type of logic tests on them
        if(person.Name.Equals("Baddie") && city.ZIP == 123456)
        {
            return country.name.Equals("Australia");
        }
        else
        {
            return false;
        }         
    }

PropertiesMustMatchAttribute просто использует Reflection для выполнения общей задачи. Я попытался разбить код на части, чтобы сделать его более читабельным/легким для понимания.

3
ответ дан 1 December 2019 в 02:55
поделиться

Possible Dupe:

Writing a CompareTo DataAnnotation Attribute

Ответы на ваши вопросы должны быть там, и по крайней мере это указывает на эту статью в блоге:

http://byatool.com/mvc/custom-data-annotations-with-mvc-how-to-check-multiple-properties-at-one-time/


Чтобы сообщение об ошибке отображалось, вы должны использовать:

<%: Html.ValidationMessage("") %>

Что происходит, так как вы проверяете на уровне класса, вы получаете ModelState с ключом, он же имя свойства, обычно с пустой строкой.

3
ответ дан 1 December 2019 в 02:55
поделиться

Я сделал следующее, используя FluentValidator, если это будет полезно кому-либо, благодаря рекомендациям Дарина:

Public Class tProductValidator
Inherits AbstractValidator(Of tProduct)


Public Sub New()
    Const RetailWholsaleError As String = "You need to enter either a Retail Price (final price to user) or a Wholesale Price (price sold to us), but not both."
    Dim CustomValidation As System.Func(Of tProduct, ValidationFailure) =
     Function(x)
         If (x.RetailPrice Is Nothing AndAlso x.WholesalePrice Is Nothing) OrElse (x.RetailPrice IsNot Nothing AndAlso x.WholesalePrice IsNot Nothing) Then
             Return New ValidationFailure("RetailPrice", RetailWholsaleError)
         End If
         Return Nothing
     End Function

    Custom(CustomValidation)
End Sub

End Class

как обычно, я был обманут, думая, что MVC - это законченный фреймворк, в котором возможны сценарии реального мира. Какого черта они публикуют такие вещи и даже не упоминают об ограничениях, которых я не понимаю, мы, разработчики, тогда сталкиваемся с проблемами, которые становятся кошмаром, или нам приходится полагаться на сторонние материалы, чтобы делать то, что по сути является ответственностью MVC, и если сторонние элементы не были доступны - что тогда?

это не первый серьезный откат, который я нашел в mvc 2.0, список продолжает расти.

уверен, что команда продолжает приводить эти «крутые» примеры того, как простые вещи используются на воображаемых примерах из нереального мира, а когда дело доходит до реальных вещей, это похоже на «черт возьми, мы не знаем и не заботимся, и мы не будем рассказывать вам о это, вам просто нужно столкнуться с этим и разобраться самостоятельно »типа deal

о, а обновление нескольких частей представления за один цикл туда и обратно по-прежнему невозможно, если вы не используете js-хак и не вырезаете возвращаемый html up и назначить его разным div ... вы даже не можете вернуть несколько представлений или, по крайней мере, обновить несколько областей страницы изначально (за одну поездку туда и обратно), это просто грустно.

Может быть, когда MVC достигнет версии 3.0, он действительно будет завершен, скрестив пальцы, поскольку структура dotnet не была реально «завершена» до clr 3.5 и включения linq / EF to SQL ...

1
ответ дан 1 December 2019 в 02:55
поделиться