ASP.NET MVC 3 - выберите, какое свойство модели проверяет каждая кнопка отправки - PullRequest
1 голос
/ 17 июня 2011

У меня есть представление с тремя кнопками отправки. Первая кнопка должна проверять некоторые поля, вторая кнопка должна проверять другие поля, третья кнопка ничего не проверяет. Как я могу сделать это как на стороне клиента (ненавязчиво), так и на стороне сервера?

Ответы [ 2 ]

0 голосов
/ 17 июня 2011

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

Итак, запустите новый ASP.NETПроект MVC 3 с использованием шаблона по умолчанию и установка пакета FluentValidation.MVC3 NuGet (текущая стабильная версия 2.0.0.0).

Затем давайте определим модель представления:

public class MyViewModel
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
}

Теперь мыМожно предположить, что при нажатии button1 требуется Field1, а при нажатии button2 требуется Field2, а при нажатии button3 ничего из них не требуется.Вымышленный сценарий, но довольно близкий к вашим требованиям.

Теперь давайте определим два разных беглых валидатора для этой модели, соответствующих каждому button1 и button2:

public class MyModelValidator1 : AbstractValidator<MyViewModel>
{
    public MyModelValidator1()
    {
        RuleFor(x => x.Field1)
            .NotEmpty();
    }
}

public class MyModelValidator2 : AbstractValidator<MyViewModel>
{
    public MyModelValidator2()
    {
        RuleFor(x => x.Field2)
            .NotEmpty();
    }
}

Теперь, потому что этотолько во время выполнения мы знаем, какая кнопка нажата, нам нужно применить правильный валидатор на основе значения в запросе.Итак, давайте напишем собственную фабрику поставщиков валидаторов:

public class MyFactory : IValidatorFactory
{
    private readonly Func<HttpContextBase> _contextProvider;
    public MyFactory(Func<HttpContextBase> contextProvider)
    {
        _contextProvider = contextProvider;
    }

    public IValidator GetValidator(Type type)
    {
        if (type == typeof(MyViewModel))
        {
            var context = _contextProvider();
            if (!string.IsNullOrEmpty(context.Request["button1"]))
            {
                return new MyModelValidator1();
            }
            if (!string.IsNullOrEmpty(context.Request["button2"]))
            {
                return new MyModelValidator2();
            }
        }
        return null;
    }

    public IValidator<T> GetValidator<T>()
    {
        return (IValidator<T>)GetValidator(typeof(T));
    }
}

и зарегистрируем ее в Application_Start:

ModelValidatorProviders.Providers.Add(
    new FluentValidationModelValidatorProvider(
        new MyFactory(() => new HttpContextWrapper(HttpContext.Current))
    )
);

, и это почти все.Теперь то, что осталось, тривиально.

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        return Content("Thanks for submitting", "text/plain");
    }
}

и вид:

@model MyViewModel

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Field1)
        @Html.EditorFor(x => x.Field1)
        @Html.ValidationMessageFor(x => x.Field1)
    </div>

    <div>
        @Html.LabelFor(x => x.Field2)
        @Html.EditorFor(x => x.Field2)
        @Html.ValidationMessageFor(x => x.Field2)
    </div>

    <input type="submit" value="Submit with button 1" name="button1" />
    <input type="submit" value="Submit with button 2" name="button2" />
    <input type="submit" value="Submit with button 3" name="button3" />
}
0 голосов
/ 17 июня 2011

Скорее всего, с большим количеством ручного использования, особенно если вы хотите, чтобы он был ненавязчивым. Вам нужно будет создать что-то вроде <input data-validationgroup="group1"..., а затем нажать на действие, чтобы ваш код javascript подтвердил то, что вы хотите. Я полагаю, что jQuery Validate имеет некоторую поддержку наборов правил, но вам придется это выяснить.

Вам нужно будет выполнить аналогичную последовательность на стороне сервера и создать классы / блоки / методы проверки типов правил, которые вы интерпретируете действие отправки для соответствующего набора правил. В этой части я бы посмотрел библиотеку, подобную FluentValidation.

Для достижения того, чего вы хотите, очень маловероятно, что вы сможете достичь этого, используя атрибуты DataAnnotations в своем классе модели.

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