Asp.NET MVC-проверка модели вне контроллера

Я строю ASP.NET проект MVC и собирается для следующей архитектуры:

  • A базовый проект, который имеет модели, проверку, dto, логику и т. д.
  • A ServiceStack API проект, который действует как мой REST API
  • An ASP.NET MVC Web проект, который является UI

Итак, предположим, я хочу добавить пользователя. Я определяю NewUserInputModel на базовый. Я даю ему немного. аннотации данных, такие как [Required]. После этого Web project выполнит проверку на стороне клиента на основе этих аннотаций.

мой вопрос касается проверки на стороне сервера. Я хочу проверить NewUserInputModel используя те же правила, которые используются на стороне клиента, и я хочу, чтобы запустить проверку погоды NewUserInputModel на API или Web.

Я понимаю, что могу позвонить ModelState.IsValid из a Контроллер в Web project-но я хочу назвать эту проверку из базовый проект так, чтобы вся логика проверки жила в базовый. Таким образом, независимо от того, как эта модель попадает в базовый логика, я всегда называю одну и ту же проверку. Я не хочу сливать System.Web ссылка на мой базовый.

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

заранее спасибо за любую помощь.

4 ответов


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

содержание модели представления в веб-проекте также позволяют использовать атрибуты проверки MVC, такие как RemoteAttribute.

Я не говорю, что ваша конструкция пахнет, но я думаю, что хорошо отделить логику презентации от вашего основного слоя.


Я считаю ваш подход хорошим. Сопоставление одного набора моделей с другим может привести к некоторым ошибкам.

код, который вы ищете это:

using System.ComponentModel.DataAnnotations;

var context = new ValidationContext(model, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(model, context, results);
if (!isValid)
    throw new Exception("Model is not valid because " + string.Join(", ", results.Select( s => s.ErrorMessage).ToArray()));

Подробнее см. http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationcontext.aspx или http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx


мой подход к этому путем быстрого мышления-сделать что-то подобное. В бизнес-слое create

public class ValidationMessage
{
    public ValidationMessage(string message, ValidationMessageType messageType)
    {
        Message = message;
        MessageType = messageType;
    }

    public string Message { get; private set; }
    public ValidationMessageType MessageType { get; private set; }
}

public enum ValidationMessageType
{
    Info,
    Warning,
    Error,
}

теперь есть пример сервиса

public interface ISomeService
{
    List<ValidationMessage> Edit(SomeModel item);
}

теперь в контроллере вы вызываете службу и передаете сообщения проверки в представление. Возможно, потребуется использовать ViewBag и передать весь список. В представлении вы можете выделить Info, Warning, Error. Например, вы можете вернуть сообщение об успехе с типом Info или вообще ничего и в контроллере создайте сообщение об успехе.

обычно этот подход является более кодированием, но более гибким. В идеале сервис будет проверять все, но для небольших проектов, чтобы избежать дублирования проверки, как заявил Хенк Моллема в своем ответе, вы можете выполнить проверку ввода пользователя через ViewModel и в сервисе просто проверить только критические бизнес-правила.

ValidationMessageType также может быть излишним, поэтому можно вернуть только список из службы как список ошибок и пустой список будет означать успех.


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

Это может быть полезным http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2