#c# #validation #model-view-controller
#c# #проверка #model-view-controller
Вопрос:
Специфическая функциональность проверки модели MVC, которую я хочу использовать, заключается в проверке данных ДО того, как они были назначены свойствам экземпляра объекта.
Например, если у меня есть класс:
public class Test
{
[Required(ErrorMessage="Id is required")]
public int Id { get; set; }
[Required(ErrorMessage="Name is required")]
[RegularExpression(Constants.SomeRegex, ErrorMessage = "Please enter a valid value for Name")]
public int Name { get; set; }
}
Я хочу иметь возможность проверить, что значение, присвоенное ‘Id’, может быть, по крайней мере, присвоено, прежде чем пытаться создать экземпляр. В этом случае это означало бы возможность присвоения целому числу, поэтому значение «ABC» не пройдет проверку.
Конечно, я не могу создать экземпляр Test со значением «ABC» для Id, его нельзя назначить Int32.
Контроллеры MVC реализуют эту функциональность — сообщения об ошибках будут возвращены до того, как экземпляр класса модели может быть создан.
С этой целью я до сих пор пытался использовать System.ComponentModel.Примечания к данным.Валидатор
public bool IsValid(IDictionary<object, object> data, out OfferConfig offerConfig)
{
offerConfig = new OfferConfig();
var context = new ValidationContext(offerConfig, data);
var results = new List<ValidationResult>();
return Validator.TryValidateObject(offerConfig, context, results, true);
}
И передача экземпляра, реализующего IDictionary
var dict = new Dictionary<object, object>
{
{"Id", dataTable.Rows[i][0].ToString()},
{"Name", dataTable.Rows[i][1].ToString()}
}
Вот так:
Test testInstance;
bool isValid = IsValid(dict, out testInstance);
Но, возможно, средство проверки работает не так, как я ожидаю. Предполагается, что аргумент data является строковым представлением свойств модели? Результаты проверки отображаются так, как если бы значения просто не были назначены, а не были неверными.
Надеюсь, кто-нибудь сможет увидеть, чего я пытаюсь здесь достичь…
Комментарии:
1. Альтернативное решение — сделайте свойство строкой и напишите пользовательский валидатор, чтобы проверить, что строка может быть преобразована в целое число. Затем напишите другое свойство, которое вернет значение в виде целого числа для использования в контроллере.
2. Это хорошее предложение, но я предполагаю, что то, что я пытаюсь сделать, должно быть возможным, поскольку это делает MVC. Если я могу избежать создания второго класса, это было бы лучше (свойства должны оставаться в текущих типах данных по причинам, которые я не буду здесь описывать)
3. Я не уверен, что вы имеете в виду — если значение не будет привязано к свойству, свойство просто примет значение по умолчанию (если только фреймворк не считает, что он может его привязать, и произойдет сбой, что является сценарием исключения), кроме того (для реальных сценариев проверки) значения присваиваются модели, но
Model.IsValid
имеют значение false — способ отразить это с помощью строкового свойства и пользовательского средства проверки.4. Итак, в приведенном выше примере, если бы я попытался отправить форму в действие контроллера, а значением для id было ‘abc’, MVC вернул бы ошибку проверки, сообщающую, что это недопустимое значение, независимо от того, добавил ли я какие-либо атрибуты проверки. Именно это поведение я хочу использовать вне контроллера.
5. Работа в вашем комментарии работает, но это означает, что мне пришлось создать дополнительный класс.
Ответ №1:
Просто создайте новый атрибут проверки, в который вы разместите нашу логику проверки. Вот так:
public class StringIdLengthRangeAttribute : ValidationAttribute
{
public int Minimum { get; set; }
public int Maximum { get; set; }
public StringLengthRangeAttribute()
{
this.Minimum = 0;
this.Maximum = int.MaxValue;
}
public override bool IsValid(object value)
{
string strValue = value as string;
if (!string.IsNullOrEmpty(strValue))
{
int len = strValue.Length;
return len >= this.Minimum amp;amp; len <= this.Maximum;
}
return true;
}
}
Это пример проверки длины — замените его своей логикой проверки.
И ваш класс:
public class Test
{
[Required]
[StringIdLengthRange(Minimum = 10, Maximum = 20)]
public string Id { get; set; }
}
С таким атрибутом вы можете использовать эту логику в любых других полях.
Комментарии:
1. Извините, это не то, что я спрашивал.