Реализация атрибута проверки уровня класса, который записывает в свойство внутри класса - PullRequest
1 голос
/ 06 июля 2010

Я создаю сайт ASP.NET MVC, на котором я хочу украсить свои ViewModels атрибутами проверки. Одной из вещей, которые я хочу проверить, является то, что адрес, который пользователь отправляет через форму, является геокодируемым. Для этого я уже создал пользовательский ValidationAttribute и применил к своему StreetAddress свойству.

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

Чтобы выполнить такую ​​задачу, я думаю, что мне нужно создать свойство широты и долготы в моей модели представления. Само представление не будет касаться этих двух свойств, но атрибут validation либо сообщит об ошибке геокодирования и вернет представление, либо запишет результаты в свойствах.

Чтобы атрибут валидации имел доступ к 3 свойствам, он должен применяться ко всему классу. Я пока не знаю, как это сделать, но вот для чего этот вопрос.

ОБНОВЛЕНИЕ: Благодаря этому ответу я выяснил, как создать атрибут проверки уровня класса. Ссылка в ответе также демонстрирует, как читать содержимое свойства внутри класса (через Reflection). Тем не менее, я до сих пор не понял, как написать свойство.


Мои вопросы

Как создать ValidationAttribute, который можно применить ко всему классу? Ниже я разместил код, который хочу преобразовать в атрибут, который можно применить к моей модели представления:

public class GeocodableAttribute : ValidationAttribute
    {
        public GeocodableAttribute() : base()
        {
            ErrorMessage = "We weren't able to find that location.";
        }
        public override bool IsValid(object value)
        {
            if (value == null) //we don't care if it's required or not.
            {
                return true;
            }
            var address = (string)value;
            var response = Geocoder.CallGeoWS(address.Trim());
            if(response.Status=="ZERO_RESULTS")
            {
                return false;
            }
            return true;
        }
    }


Как мне записать атрибут в определенные свойства класса , к которому он применяется? Когда я применяю этот атрибут к моей ViewModel, я хочу, чтобы он записывал успешные результаты геокодирования в два свойства и return true. Как я могу это реализовать?

ОБНОВЛЕНИЕ № 2: Мне кажется, я только что выяснил, как написать свойство. Должен ли работать следующий код?

    private static void WritePropertyValue(object obj, string propertyName, object valueToWrite)
    {
        if (obj == null) return null;
        var type = obj.GetType();
        var propertyInfo = type.GetProperty(propertyName);
        if (propertyInfo == null) return null;
        propertyInfo.SetValue(obj, valueToWrite, null);
    }

Будет ли это нарушать проверку на стороне клиента для других атрибутов / свойств? У меня есть другие свойства в моей ViewModel, которые я украсил встроенными атрибутами ValidationAttributes, например [Required] и [Range]. Я также включил проверку на стороне клиента для них. Будет ли применение моего нового атрибута ко всему классу ViewModel полностью нарушать проверку на стороне клиента или проверка на других свойствах будет выполняться на клиенте, а затем будет выполняться полная проверка на сервере?

1 Ответ

1 голос
/ 06 июля 2010

1) Вы не можете получить доступ к внешнему классу через уровень свойства ValidationAttribute.

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

Создание пользовательского связующего для модели: http://www.singingeels.com/Articles/Model_Binders_in_ASPNET_MVC.aspx

2) Нет. Вы пробовали?

Это почти дубликат.Я бы проверил вопрос и ответы для моего представления.Он может содержать отдельную технику, проверку на уровне класса, которая может делать то, что вам нужно.

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