Как вы выполняете проверку модели веб-форм?

#c# #asp.net #validation #entity-framework-4 #model

#c# #asp.net #проверка #entity-framework-4 #Модель

Вопрос:

У нас есть приложение с тремя уровнями: пользовательский интерфейс, бизнес и данные. Уровень данных содержит Entity Framework v4 и автоматически генерирует наши объекты entity. Я создал класс buddy для объекта VendorInfo :

 namespace Company.DataAccess
{
    [MetadataType(typeof(VendorInfoMetadata))]
    public partial class VendorInfo
    {
    }

    public class VendorInfoMetadata
    {
        [Required]
        public string Title;

        [Required]
        public string Link;

        [Required]
        public string LinkText;

        [Required]
        public string Description;
    }
}
  

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

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

Есть идеи?

Спасибо всем.

Комментарии:

1. К сожалению, я не могу ответить на конкретный вопрос, касающийся проверки аннотации данных в WebForms. Но я хотел бы порекомендовать вам рассмотреть возможность переноса шаблона T4 в отдельную сборку модели / бизнес-объектов, чтобы предотвратить прямую зависимость вашего пользовательского интерфейса от уровня данных.

Ответ №1:

Я решил это. Похоже, что серверный элемент управления, который я нашел , не был предназначен для чтения полей в классе buddy через атрибут MetadataType. Я изменил код, чтобы искать его атрибуты проверки в классе buddy, а не в самом классе entity.

Вот измененная версия связанного серверного элемента управления:

     [DefaultProperty("Text")]
    [ToolboxData("<{0}:DataAnnotationValidator runat=server></{0}:DataAnnotationValidator>")]
    public class DataAnnotationValidator : BaseValidator
    {
        #region Properties

        /// <summary>
        /// The type of the source to check
        /// </summary>
        public string SourceTypeName { get; set; }

        /// <summary>
        /// The property that is annotated
        /// </summary>
        public string PropertyName { get; set; }

        #endregion

        #region Methods

        protected override bool EvaluateIsValid()
        {
            // get the type that we are going to validate
            Type source = GetValidatedType();

            // get the property to validate
            FieldInfo property = GetValidatedProperty(source);

            // get the control validation value
            string value = GetControlValidationValue(ControlToValidate);

            foreach (var attribute in property.GetCustomAttributes(
                     typeof(ValidationAttribute), true)
                       .OfType<ValidationAttribute>())
            {
                if (!attribute.IsValid(value))
                {
                    ErrorMessage = attribute.ErrorMessage;
                    return false;
                }
            }
            return true;
        }

        private Type GetValidatedType()
        {
            if (string.IsNullOrEmpty(SourceTypeName))
            {
                throw new InvalidOperationException(
                  "Null SourceTypeName can't be validated");
            }

            Type validatedType = Type.GetType(SourceTypeName);
            if (validatedType == null)
            {
                throw new InvalidOperationException(
                    string.Format("{0}:{1}",
                      "Invalid SourceTypeName", SourceTypeName));
            }

            IEnumerable<MetadataTypeAttribute> mt = validatedType.GetCustomAttributes(typeof(MetadataTypeAttribute), false).OfType<MetadataTypeAttribute>();
            if (mt.Count() > 0)
            {
                validatedType = mt.First().MetadataClassType;
            }

            return validatedType;
        }

        private FieldInfo GetValidatedProperty(Type source)
        {
            FieldInfo field = source.GetField(PropertyName);
            if (field == null)
            {
                throw new InvalidOperationException(
                  string.Format("{0}:{1}",
                    "Validated Property Does Not Exists", PropertyName));
            }
            return field;
        }

        #endregion
    }
  

Этот код просматривается только в классе buddy. Если вы хотите, чтобы он проверял фактический класс, а затем его вспомогательный класс, вам придется соответствующим образом изменить его. Я не стал утруждать себя этим, потому что обычно, если вы используете класс buddy для атрибутов проверки, это потому, что вы не можете использовать атрибуты в основном классе объектов (например, Entity Framework).

Ответ №2:

Для проверки модели в веб-формах я использую библиотеку DAValidation. Он поддерживает проверку на стороне клиента (включая ненавязчивую проверку), расширяемость основана на тех же принципах, что и в MVC. Он лицензирован на MS-PL и доступен через Nuget.

И вот немного устаревшая статья, описывающая, с какими мыслями создавался элемент управления.