Пользовательское сообщение проверки не отображается с использованием IValidatableObject - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть простая форма с 2 кнопками (Отмена и Отправить) и TextArea.Пользователь вводит список адресов электронной почты и нажимает кнопку отправки.Я пытаюсь выяснить, почему мое пользовательское сообщение не отображается при отправке формы.Я знаю, что логика проверки работает, поскольку она запускает мое правило [Обязательный], и я вижу сообщение об ошибке для этого:

enter image description here

Однако, когда я печатаюв таких данных, как «test @» и затем отправить, срабатывает логика в Validate , но я не вижу свое сообщение об ошибке " Пожалуйста, убедитесь, что все электронные письма действительны ».Может ли кто-нибудь указать, что я делаю неправильно.

Это моя модель:

public class ShareModel : IValidatableObject
{
    [HiddenInput] public string Title { get; set; }

    [Required]
    public string Emails { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // custom validation logic here
        yield return new ValidationResult($"Please make sure that all of the emails are valid", new[] { "Emails" });
    }
}

Это мое мнение:

<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
    <!-- Modal content-->
    <div class="modal-content">
        <div class="modal-header">
            <h4 class="modal-title">Share Workbook - @Model.Title</h4>

        </div>

        @using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {@id = "partialform"}))
        {
            <div class="modal-body">

                <label>@BaseLanguage.Share_workbook_Instruction_text</label>
                <div class="form-group">
                    <textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
                    <span asp-validation-for="Emails" class="text-danger"></span>
                </div>

                <input asp-for="Title"/>
            </div>
            <div class="modal-footer">
                <button type="submit" class="btn btn-primary">Share</button>
                <button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
            </div>
        }

    </div>
</div>

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Согласно этому сообщение IValidatableObject не рассматривается на стороне клиента. Чтобы отобразить пользовательское сообщение об ошибке из пользовательской проверки, вам нужно реализовать пользовательский ValidationAttribute, который также реализует интерфейс IClientModelValidator, как описано здесь .

0 голосов
/ 12 апреля 2019

Для дальнейшего использования, как объяснил Александр, я должен был использовать оба значения ValidationAttribute, IClientModelValidator:

ShareModel

public class ShareModel
{
    [HiddenInput] public string Title { get; set; }

    [Required]
    [IsEmailAttribute(ErrorMessage = "Check all of the emails you have typed")]
    public string Emails { get; set; }
}

public class IsEmailAttribute : ValidationAttribute, IClientModelValidator
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
         return new ValidationResult("Check emails!");
    }

    public void AddValidation(ClientModelValidationContext context)
    {
        MergeAttribute(context.Attributes, "data-val", "true");
        var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
        MergeAttribute(context.Attributes, "data-val-isEmail", errorMessage);
    }

    private bool MergeAttribute(
        IDictionary<string, string> attributes,
        string key,
        string value)
    {
        if (attributes.ContainsKey(key))
        {
            return false;
        }
        attributes.Add(key, value);
        return true;
    }

}

_ShareView.cshtml

@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.ShareModel

<!-- Modal -->
<div class="modal fade" id="shareFormModal" role="dialog">
    <div class="modal-dialog modal-md">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Share Workbook - @Model.Title</h4>

            </div>

            @using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {@id = "partialform"}))
            {
                <div class="modal-body">

                    <label>@BaseLanguage.Share_workbook_Instruction_text</label>
                    <div class="form-group">
                        <textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
                        <span asp-validation-for="Emails" class="text-danger"></span>
                    </div>

                    <input asp-for="Title"/>
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-primary">Share</button>
                    <button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                </div>
            }

        </div>
    </div>
</div>

index.cshtnl

@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.WorkBookModel
@{
}

@section BodyFill
{
    <div id="shareFormContainer">
        <!--PLACEHOLDER FOR SHARE DIALOG -->
        @{
            @Html.Partial("_ShareView", new ShareModel())
        }

    </div>

    <div class="workbook-container">
        <table class="table">
            <tbody>
                @foreach (var workbook in Model.Workbooks)
                {
                    <tr>
                        <td>@Html.ActionLink(workbook.Name, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
                        <td>
                            <button title="Share" class="share-button" onclick='showSharingView("@workbook.Name")'>&nbsp;</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
}

@section Scripts
{
    <!--Load JQuery 'unobtrusive' validation -->
    @await Html.PartialAsync("_ValidationScriptsPartial")
    <script type="text/javascript">

        function showSharingView(title) {
            var url = "@Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
            $('#shareFormContainer').load(url,
                function() {
                    $('#shareFormModal').modal("show");
//                    // We need to manually register the form for validation as the dialog is
//                    // not included in the page when it initially loads
                    $.validator.unobtrusive.parse("#partialform");

                    // email validation
                    $.validator.addMethod("isEmail",
                        function (value, element, parameters) {
                            // TODO CLIENT SIDE VALIDATETION LOGIC HERE
                            return false;
                        });
                    $.validator.unobtrusive.adapters.add("isEmail",
                        [],
                        function(options) {
                            options.rules.isEmail = {};
                            options.messages["isEmail"] = options.message;
                        });
                });
        }

    </script>
}
...