Простая проверка ASP.Net MVC 1.0 - PullRequest
5 голосов
/ 14 апреля 2010

В текущем проекте, над которым мы работаем, мы еще не обновили до MVC 2.0, поэтому я работаю над реализацией простой проверки с помощью инструментов, доступных в версии 1.0.

Я ищу отзывы о том, как я это делаю.

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

Вот краткий пример

public FooController : Controller
{
     public ActionResult Edit(User user)
     {
          user.ValidateModel(this);

          if (ModelState.IsValid)
               .......
               .......
      }
}

А моя подпись проверки модели выглядит как

public void ValidateModel(Controller currentState)

Какие проблемы вы можете увидеть с этим? Могу ли я выйти на обед о том, как я хочу это сделать?

Ответы [ 2 ]

1 голос
/ 14 апреля 2010

Проблема, которую я вижу при таком подходе, заключается в том, что ваша логика проверки связана с контроллером. На самом деле валидатору не нужен контроллер, а только IDictionary<string, ModelState> для установки ошибок.

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

Итак, ваш код действия будет выглядеть так:

public FooController : Controller
{
     public ActionResult Edit(User user)
     {
         if (ModelState.IsValid)
         {

         }
         return View();
     }
}

Ошибки модели добавляются при привязке. Вот хорошая статья , демонстрирующая интеграцию этой библиотеки с ASP.NET MVC. Модульное тестирование Ваша логика проверки также очень проста и удобочитаема.

0 голосов
/ 14 апреля 2010

Для проектов MVC 1.0 мы делаем следующее:

/* In model class */

public void Validate(string dealerId)
{
    ExceptionList exceptions = new ExceptionList();

    if (String.IsNullOrEmpty(this.UserName))
    {
        exceptions.Exceptions.Add(new InvalidFieldException("Error message", "ContractType"));
    }

    ... other validations ...

    if (exceptions.Exceptions.Count > 0)
    {
        throw exceptions;
    }
}


/* In controller */

public virtual ActionResult UpdateProfile(User user)
{

    try
    {
        user.Validate();
    }
    catch (ExceptionList ex)
    {
        ex.CopyToModelState(ModelState);
    }
}


/* Custom types (ExceptionList / InvalidFieldException) */

[Serializable]
public class ExceptionList : Exception
{
    private List<Exception> exceptions;
    public List<Exception> Exceptions
    {
        get { return exceptions; }
        set { exceptions = value; }
    }

    public ExceptionList() { Init(); }
    public ExceptionList(string message) : base(message) { Init(); }
    public ExceptionList(string message,
        System.Exception inner)
        : base(message, inner) { Init(); }
    protected ExceptionList(
        System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context)
        : base(info, context) { Init(); }


    private void Init()
    {
        Exceptions = new List<Exception>();
    }
}

[Serializable]
public class InvalidFieldException : Exception
{
    private string fieldName;
    public string FieldName
    {
        get
        {
            return fieldName;
        }
        set
        {
            fieldName = value;
        }
    }

    private string fieldId;
    public string FieldId
    {
        get
        {
            return fieldId;
        }
        set
        {
            fieldId = value;
        }
    }

    public InvalidFieldException() { }
    public InvalidFieldException(string message) : base(message) { }
    public InvalidFieldException(string message, string fieldName)
        : base(message)
    {
        this.fieldName = fieldName;
    }
    public InvalidFieldException(string message, string fieldName, string fieldId)
        : base(message)
    {
        this.fieldName = fieldName;
        this.fieldId = fieldId;
    }
    public InvalidFieldException(string message, System.Exception inner)
        : base(message, inner) { }
    public InvalidFieldException(string message, string fieldName,
        System.Exception inner)
        : base(message, inner)
    {
        this.fieldName = fieldName;
    }
    public InvalidFieldException(string message, string fieldName, string fieldId,
         System.Exception inner)
        : base(message, inner)
    {
        this.fieldName = fieldName;
        this.fieldId = fieldId;
    }


    protected InvalidFieldException(
        System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context)
        : base(info, context) { }
}


/* Extension method (to copy ExceptionList exceptions to ModelState) */

/// <summary>
/// Copies an ExceptionList to ModelState for MVC
/// </summary>
/// <param name="exList">List of exceptions</param>
/// <param name="modelState">Model state to populate</param>
/// <param name="collection">Form collection of data posted to the action</param>
/// <param name="prefix">Prefix used in view (if any)</param>
/// <param name="isCollection">Indicates whether a collection of objects are being returned from the view (requires prefix)</param>
[CLSCompliant(false)]
public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState, FormCollection collection, string prefix, bool isCollection)
{
    foreach (InvalidFieldException ex in exList.Exceptions)
        if (String.IsNullOrEmpty(prefix))
        {
            modelState.AddModelError(ex.FieldName, ex.Message);
            modelState.SetModelValue(ex.FieldName, collection.ToValueProvider()[ex.FieldName]);
        }
        else
        {
            if (isCollection)
            {
                modelState.AddModelError(prefix + "[" + ex.FieldId + "]." + ex.FieldName, ex.Message);
                modelState.SetModelValue(prefix + "[" + ex.FieldId + "]." + ex.FieldName, collection.ToValueProvider()[ex.FieldName]);
            }
            else
            {
                modelState.AddModelError(prefix + "." + ex.FieldName, ex.Message);
                modelState.SetModelValue(prefix + "." + ex.FieldName, collection.ToValueProvider()[ex.FieldName]);
            }
        }
}

    /// <summary>
    /// Copies an ExceptionList to ModelState for MVC
    /// </summary>
    /// <param name="exList">List of exceptions</param>
    /// <param name="modelState">Model state to populate</param>
    [CLSCompliant(false)]
    public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState)
    {
        CopyToModelState(exList, modelState, null, false);
    }

    /// <summary>
    /// Copies an ExceptionList to ModelState for MVC
    /// </summary>
    /// <param name="exList">List of exceptions</param>
    /// <param name="modelState">Model state to populate</param>
    /// <param name="collection">Form collection of data posted to the action</param>
    [CLSCompliant(false)]
    public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState, FormCollection collection)
    {
        CopyToModelState(exList, modelState, collection, null, false);
    }

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

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