Проверка ASP.NET MVC 1.0 с помощью xVal

На самом деле меня устраивает другой метод проверки. Кажется, не так много готовых опций для проверки с помощью ASP.NET MVC 1.0. Главное, о чем я вижу, - это xVal. Однако документации на него буквально нет. На самом деле в блоге основателя вроде бы всего два поста.

В любом случае, это единственное, что я видел, что также может обеспечить проверку клиента. Моя проблема в том, что я не могу использовать вещи на основе атрибутов, потому что я создаю свои модели с помощью LLBLGen и не хочу изменять код.

Все, что я читал о xVal, говорит о возможности реализации IRulesProvider, но нет реальной информации о том, как это сделать и как его использовать. Я нашел код, который его реализует, но использует атрибуты, которые у меня нет.

Так может ли кто-нибудь дать руководство по использованию xVal, если я не кодирую свои классы моделей вручную или не собираюсь использовать DataAnnotations или что-то подобное (я открыт для альтернативы xVal, но я ничего не видел, и мне нужно придерживаться ASP.NET MVC 1.0, и мне нужна поддержка проверки на стороне клиента)?

Изменить: я не думаю, что подход частичного класса будет работать для меня, потому что я буду много генерировать код, и они будут в разных сборках.


person JustAProgrammer    schedule 17.01.2010    source источник
comment
Я не понимаю, почему частичные классы вам не подходят. Это довольно стандартный подход C # к добавлению настраиваемого поведения в классы, созданные с помощью шаблона. Не имеет значения, много ли они генерируются, так как это не изменит ваш собственный код. А что значит они будут в разных сборках? Это ограничение парциальных классов, они не могут быть в разных сборках. См. Документацию ... msdn.microsoft.com/ en-us / library / wa80x488% 28VS.80% 29.aspx   -  person Jace Rhea    schedule 19.01.2010
comment
@jacerhea, причина, по которой у меня не работают частичные классы, заключается в том, что сгенерированный код находится в другой сборке. Разве не правильно, что частичные классы должны находиться в одной сборке?   -  person JustAProgrammer    schedule 18.02.2010
comment
Я неправильно понял. Я думал, вы говорили, что они на самом деле собираются участвовать в разных собраниях, а я говорил, что это невозможно. Да, частичные классы должны быть частью одной сборки. Это кажется странным требованием - иметь разные части одного и того же класса в разных модулях кода. Думали ли вы, что, возможно, эти другие требования заставляют вас принимать неправильные архитектурные решения? В любом случае, если вы хотите реализовать собственный IRulesProvider, я бы предложил загрузить исходный код xVal, где можно посмотреть код IRulesProvider для Castle и NHibernate.   -  person Jace Rhea    schedule 18.02.2010


Ответы (2)


Вы можете использовать xVal с LLBLGen или любыми другими сгенерированными ORM классами, используя атрибут MetadataType в частичном классе. Например, если у вас есть сгенерированный LLBL объект под названием UserEntity, вы должны создать частичный класс и пометить его атрибутом MetadataType следующим образом:

[MetadataType(typeof(UserEntityMetaData))]
public partial class UserEntity
{
}

Затем вы создадите класс Meta, в котором вы можете разметить свойства соответствующими атрибутами, например:

public class UserEntityMetaData
{
    [Required()]
    [StringLength(50)]
    [DataType(DataType.EmailAddress)]
    public object EmailAddress { get; set; }
    [Required()]
    [StringLength(32)]
    [DataType(DataType.Password)]
    public object Password { get; set; }
    [Required()]
    [StringLength(25)]
    public object FirstName { get; set; }
    [Required()]
    [StringLength(25)]
    public object LastName { get; set; }
}

Это позволит вам не изменять сгенерированный LLBL код, а только ваши собственные частичные классы. Единственная загвоздка в том, что вам понадобится как частичный класс, так и класс Meta в том же пространстве имен, что и сгенерированные классы сущностей. Вам не обязательно этого делать, но это упрощает задачу, когда вы вызываете проверку xVal.

person Jace Rhea    schedule 17.01.2010

В дополнение к тому, что сказал jcerhea, вам также необходимо изменить способ настройки класса DataAnnotationsValidationRunner для обработки классов «приятелей» в методе GetErrors, например

    namespace Entities
    {
        public static class DataAnnotationsValidationRunner
        {
            public static IEnumerable<ErrorInfo> GetErrors(object instance)
            {
                var metadataAttrib = instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();
                var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : instance.GetType();
                var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>();
                var modelClassProperties = TypeDescriptor.GetProperties(instance.GetType()).Cast<PropertyDescriptor>();

                return from buddyProp in buddyClassProperties
                       join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
                       from attribute in buddyProp.Attributes.OfType<ValidationAttribute>()
                       where !attribute.IsValid(modelProp.GetValue(instance))
                       select new ErrorInfo(buddyProp.Name, attribute.FormatErrorMessage(string.Empty), instance);
            }
        }
    }
person Turnkey    schedule 17.01.2010