Пользовательское сообщение об ошибке от IValidatableObject в MVC - PullRequest
0 голосов
/ 24 октября 2019

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

Вызывает кнопка отправкиajax-запрос:

$.ajax({
    url: "/Operazioni/DocumentiCondivisi",
    type: "POST",
    dataType: "application/json",
    data: {
        model: documentModel
    }
}).done( //blah ).fail( //blah );

, который запускает метод действия:

[HttpPost]
[ClientErrorHandler]
[UserHandler(new Role[] { Role.ADMIN, Role.ARCHIVISTA, Role.OPERATORE })]
public void DocumentiCondivisi(DocumentiCondivisiEditModel model)
{
    if (ModelState.IsValid)
    {
        // ok
    }
    else
    {
        string ers = "<ul>Non è stato possibile registrare l'operazione a causa dei seguenti errori:";
        foreach (ModelState state in ModelState.Values)
        {
            foreach (ModelError error in state.Errors)
            {
                ers += $"<li>{error.ErrorMessage}</li>";
            }
        }
        ers += "</ul>";
        throw new Exception(ers);
    }
}

Здесь выдается исключение, чтобы я мог использовать его сообщение в методе обратного вызова fail() ajaxзапросить и добавить его к части документа, чтобы показать его пользователю. Теперь модель имеет собственную логику проверки

public class DocumentiCondivisiEditModel : IValidatableObject
{
    public Document Doc { get; set; }
    public IEnumerable<int> Fascicoli { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Doc.NumeroProtocollo == 0 || Doc.DataProtocollo == DateTime.MinValue)
        {
            yield return new ValidationResult("Devi selezionare un documento");
        }
        else
        {
            if (Doc.Chiavi == null || Doc.Chiavi.Count == 0)
            {
                yield return new ValidationResult("Inserire almeno una parola chiave");
            }

            if (Doc.Cartella == null || Doc.Cartella.ID == 0)
            {
                yield return new ValidationResult("Selezionare una cartella di destinazione");
            }
        }

        if (Fascicoli == null || Fascicoli.Count() == 0)
        {
            yield return new ValidationResult("Selezionare almeno un fascicolo nel quale inserire il documento");
        }
    }
}

Когда модель действительна, проблем нет - все работает отлично. Когда возвращается какой-либо из ValidationResult, я ожидал бы, что ModelState.Keys будет отражать логику проверки, вместо этого, осматривая объект, я вижу, что он представляет эти четыре элемента:

ModelState.Keys object

и, фактически, если я пытаюсь представить почти пустую модель, подобную этой

JS Object as sent from the AJAX request

, я получаю эти сообщения:

Client error message

Как видите, сообщения ValidationResult полностью игнорируются. Что меня действительно удивляет, так это то, что у объекта Documento нет атрибута [Required], поэтому я не могу понять, откуда берутся эти 4 ключа в объекте ModelState. Я думаю, что они связаны с тем фактом, что они отправляются с нулевым значением в запросе, но затем привязка создает для них значения по умолчанию (т. Е. Int - 0, а datetime - DateTime.MinValue), о которых я и позабочусь в проверке. метод. Есть предложения?

Спасибо, Давиде.

...