Показывать ошибки из контроллера в оповещение Boostrap - PullRequest
0 голосов
/ 22 мая 2018

Я ищу способ добавить сообщение об ошибке, чтобы показать ошибки.В настоящее время у меня есть это в моем контроллере для обработки ошибок:

public partial class SongsManagementController : BaseController
{

    private const string NoDataFound = "No data found.";
    private const string InvalidDataPosted = "Invalid data posted";
    private const string InvalidRequest = "Invalid request.";
    private const string VerificationFailedUnexpectedError = "The following song failed to verify due to an unexpected error, please contact RightsApp support.";
    private const string ConcurrencyError = "The following song failed to verify as another user has since changed its details.";

    [HttpPost]
    [Route("VerifyNewSongs")]
    [AuthorizeTenancy(Roles = "super,administrator")]
    public async Task<ActionResult> VerifyNewSongs(List<VerifySongViewModel> verifySongViewModels)
    {
        // Not AJAX method - refuse
        if (!Request.IsAjaxRequest())
            return RedirectToAction("NewSongs", "SongsManagement");

        if (verifySongViewModels.NullOrEmpty())
        {
            // return error;
            return Json(new JsonBaseModel
            {
                success = false,
                message = InvalidRequest,
                data = null,
                errors = new List<string>
                {
                    InvalidDataPosted
                }
            });
        }
        foreach (var verifySong in verifySongViewModels)
        {
            if (verifySong.WorkId == default(Guid) || verifySong.RowVersion == default(Guid))
            {
                return Json(new JsonBaseModel
                {
                    success = false,
                    message = InvalidDataPosted,
                    data = null,
                    errors = new List<string>
                    {
                        $"Invalid data posted for following song.",
                        $"Song Title: {verifySong.SongTitle}",
                        $"Song Id: {verifySong.UniqueCode}"
                    }
                });
            }
            var work = await _artistAccountService.GetWorkGraphAsync(verifySong.WorkId, includeWriterAmendments: true);
            if (work == default(WorkGraphModels.Work))
            {
                return Json(new JsonBaseModel
                {
                    success = false,
                    message = NoDataFound,
                    data = null,
                    errors = new List<string>
                    {
                        $"No data found for following song.",
                        $"Song Title: {verifySong.SongTitle}",
                        $"Song Id: {verifySong.UniqueCode}"
                    }
                });
            }
            if (work.VerifiedState != Domain.Enumerators.VerifiedStateType.NotVerified)
            {
                return Json(new JsonBaseModel
                {
                    success = false,
                    message = NoDataFound,
                    data = null,
                    errors = new List<string>
                    {
                        $"Song already verified.",
                        $"Song Title: {verifySong.SongTitle}",
                        $"Song Id: {verifySong.UniqueCode}"
                    }
                });
            }
            work.RowVersion = verifySong.RowVersion;
            var workAndAmendment = new WorkGraphModels.WorkAndAmendment
            {
                Original = work,
                Amendment = null
            };
            var verifiedState = await _artistAccountService.VerifyWorkGraphAsync(workAndAmendment, GetLoggedUserId());
            if (!verifiedState.ValidationErrors.NullOrEmpty())
            {
                return Json(new JsonBaseModel
                {
                    success = false,
                    message = NoDataFound,
                    data = null,
                    errors = new List<string>
                        {
                            VerificationFailedUnexpectedError,
                            $"Song Title: {verifySong.SongTitle}",
                            $"Song Id: {verifySong.UniqueCode}"
                        }
                });
            }
            else if (!verifiedState.DatabaseErrors.NullOrEmpty())
            {
                if (!verifiedState.FatalException)
                {
                    // concurrency exception                        
                    return Json(new JsonBaseModel
                    {
                        success = false,
                        message = NoDataFound,
                        data = null,
                        errors = new List<string>
                        {
                            ConcurrencyError,
                            $"Song Title: {verifySong.SongTitle}",
                            $"Song Id: {verifySong.UniqueCode}"
                        }
                    });
                }
                else
                {
                    // fatal
                    return Json(new JsonBaseModel
                    {
                        success = false,
                        data = null,
                        errors = new List<string>
                        {
                            VerificationFailedUnexpectedError,
                            $"Song Title: {verifySong.SongTitle}",
                            $"Song Id: {verifySong.UniqueCode}"
                        }
                    });
                }
            }
        }
        return Json(new JsonBaseModel
        {
            success = true,
            message = "All songs verified successfully."
        });
    }
};

}

Это мой основной вид:

Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_SentricLayout.cshtml";
    var actionName = ViewContext.RouteData.Values["Action"].ToString();

    @* calc full account code *@
    var fullAccountCode = Model.WorkUniqueCode;
    ViewBag.Title = "New Songs";
}

@section scripts {
    @Scripts.Render("~/bundles/jqueryajaxval")
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/datetimepicker")
    <script language="javascript" type="text/javascript">
    @* DOM ready? *@
    $(function () {
        addTableStylingScripts();
        var selectFormDiv = $('.catalogSelector');
        selectFormDiv.hide();

        $(".records-selected").hide();

        // clear all filter boxes and reset search.
        $("#btnClear").click(function()
        {
            $("#newSongsSearch").find(':input').each(function ()
            {
                if (this.type === "text")
                {
                    $(this).val("");
                }
            });

            $("#btnSearch").click();
        });

        @* edit catalogue button *@
        $('#changeCat').click(function () {
            $('#errorContainer').hide();

            var label = $('#catLabel');

            if (label.is(":visible")) {
                label.hide();
                selectFormDiv.show();

                $('#changeCat').addClass("active");
            } else {
                label.show();
                selectFormDiv.hide();

                $('#changeCat').removeClass("active");
            }
        });

        @* edit dropdown *@
        $("#catalogueSelect").on("change", function () {
            @* change display on select change *@
            $('#errorContainer').hide();
            $('#catLabel').show();
            selectFormDiv.hide();
            $('#changeCat').removeClass("active");

            @* set up ajax post to controller *@
            var model = {
                AccountCode: '@fullAccountCode',
                CurrentAccountId: $('#currentAccountId').val(),
                CurrentRowVersion: $('#currentRowVersion').val(),
                NewCatalogueId: $('#catalogueSelect option:selected').val(),
                Action: '@actionName'
            };
            $.ajax({
                url: '@Url.Action("ChangeCatalogue", "ArtistAccount")',
                data: JSON.stringify(model),
                type: 'POST',
                cache: false,
                contentType: 'application/json',
                success: function (result) {
                    @* ajax worked *@
                    if (result.ChangeStatus === "Success")
                    {
                        var newSelected = $('#catalogueSelect option:selected').text();
                        $('#catLabel').html(newSelected);

                        @* update dropdown context *@
                        var newSelectedId = $('#catalogueSelect option:selected').val();
                        $('#currentCatalogue').val(newSelectedId);

                        @* update rowversion *@
                        var newRowVersion = result.OldOrNewRowVersion;
                        $('#currentRowVersion').val(newRowVersion);
                    }
                    else
                    {
                        $('#errorContainer').show();
                        $('#errorMessage').html(result.ErrorMessage);

                        @* return downdown context *@
                        var currentCatId = $('#currentCatalogue').val();
                        $("#catalogueSelect").val(currentCatId);
                        $('#catalogueSelect').select2({ width: '180px', dropdownAutoWidth: true });
                    }
                },
                error: function () {
                    @* failed *@
                    $('#errorContainer').show();
                    $('#errorMessage').html('There was a server error, please contact the support desk on (+44) 0207 099 5991.');

                    @* return downdown context *@
                    var currentCatId = $('#currentCatalogue').val();
                    $("#catalogueSelect").val(currentCatId);
                    $('#catalogueSelect').select2({ width: '180px', dropdownAutoWidth: true });
                }
            });
        });

        function loadPartialPage(url) {
            $('.spinnerOverlay').removeClass('hide');
            $.ajax({
                url: url,
                type: 'GET',
                cache: false,
                success: function (result) {
                    $('.spinnerOverlay').addClass('hide');
                    $('#tableContainer').html(result);
                    addBootstrapTooltips("#tableContainer");
                }
            });
        }
        function getSelectedWorks() {
            var selectedWorks = $(".individual:checked");
            var works = [];
            $.each(selectedWorks, function (key, value) {
                works.push(getSelectedWork(this));
            });
            return works;
        }

        // verify songs in bulk
        $(document).on("click", ".js-verify-songs", function (e) {
            e.preventDefault();
            var works = getSelectedWorks();
            verifySongs(works);
        });
        // reject songs in bulk
        $(document).on("click", ".js-reject-songs", function (e) {
            e.preventDefault();
            var works = getSelectedWorks();

        });

        function getSelectedWork(element) {
            var work = new Object();
            work.WorkId = getRowData(element, "id");
            work.RowVersion = getRowData(element, "rowversion");
            work.UniqueCode = getRowData(element, "uniqueworkid");
            work.SongTitle = getRowData(element, "songtitle");
            return work;
        }

        // verify one song
        $(document).on("click", ".js-verify-song", function (e) {
            e.preventDefault();
            var works = [];
            works.push(getSelectedWork(this));
            verifySongs(works);
        });
        // reject one song
        $(document).on("click", ".js-reject-song", function (e) {
            e.preventDefault();
            var works = [];
            works.push(getSelectedWork(this));
        });

        function verifySongs(songs) {
            $('.spinnerOverlay').removeClass('hide');
               $.ajax({
                   url: '@Url.Action("VerifyNewSongs", "SongsManagement")',
                   data: JSON.stringify(songs),
                   type: 'POST',
                   cache: false,
                   contentType: 'application/json',
                   success: function (result) {
                       $('.spinnerOverlay').addClass('hide');
                       if (result.success) {
                           loadPartialPage($(".paginate_button.active a").attr("href"));
                       }
                   },
                   error: function(error) {
                       $('.spinnerOverlay').addClass('hide');
                   }
               });
        }

        @* Pagination Async Partial Handling *@
        $(document).on("click",
            "#indexPager a",
            function() {
                if ($(this).parent().hasClass('disabled') || $(this).parent().hasClass('active'))
                    return false;
                loadPartialPage($(this).attr("href"));

                return false;
            });



        $(document).on("change",
            "#pageSizeSelector",
            function() {
                var selectedValue = $(this).val();
                loadPartialPage(selectedValue);
                return false;
            });

        @* Sorting Async Partial Handling *@
        $(document).on("click",
            "#tableHeader a",
            function()
            {
                loadPartialPage($(this).attr("href"));
                return false;
            });
        });

        // Ensure that after paging and sorting ajax calls we re-bind
        // the change event and hide the record count label.
        $(document).ajaxComplete(function() {
            $(".records-selected").hide();
            $(".individual").on("change", determineActionButtonAvailability);
            $(".selectall").click(function () {
                $(".individual").prop("checked", $(this).prop("checked"));
                determineActionButtonAvailability();
            });
        });

        // Search functions
        $('.searchDivider').click(function (e) {
            $('#searchFields').slideToggle();
            var isSearchShown = $(this).find('.caret').hasClass("caret-up");
            if (isSearchShown) {
                $(this).children('span').replaceWith('<span class="bg-white">Search <b class="caret"></b></span>');
            } else {
                $(this).children('span')
                    .replaceWith('<span class="bg-white">Search <b class="caret caret-up"></b></span>');
            }
        });

        $(".searchArea input:text").keypress(function (e) {
            if (e.which === 13) {
                e.preventDefault();
                $("#btnSearch").click();
            }
        });

        $(window).resize(function () {
            if ($(window).width() >= 1024) {
                $('#searchFields').show();
            }
        });

        $(".searchArea input:text").keypress(function (e) {
            if (e.which === 13) {
                e.preventDefault();
                $("#btnSearch").click();
            }
        });


        // Checks individual checkboxes and displays the count
        $(".individual").on("change", determineActionButtonAvailability);

        $(".selectall").click(function () {
            $(".individual").prop("checked", $(this).prop("checked"));
            determineActionButtonAvailability();
        });

        //Disable Top Verify Button if two or more checkboxes are selected.
        $('.verify-btn').prop('disabled', true);
        //Disable Action Button in the columns when more than one checkbox is selected
        $('.table-btn').prop('disabled', false);
        $(".individual").on("click", function () {
            if ($(".individual:checked").length > 1) {
                $('.table-btn').prop('disabled', true);
                $('.verify-btn').prop('disabled', false);
            }
            else {
                $('.table-btn').prop('disabled', false);
                $('.verify-btn').prop('disabled', true);
            }
        });

        // When one or more works are selected, will enable the top action menu.
        // Will disable when none selected.
        function determineActionButtonAvailability() {
            if ($(".individual:checked").length > 1) {
                $(".records-selected").show();
                $("#selected").text($(".individual:checked").length);
                $("#total").text($(".individual").length);


                $(".verify-btn").prop('disabled', false);
                if ($(".individual:checked").length > 1) {
                }
            }
            else {
                $(".records-selected").hide();
                $('.table-btn').prop('disabled', false);
                $(".verify-btn").prop('disabled', true);
            }
        }

        // Enforce only numeric input in the Unique Id search textbox.
        $(document).on("keydown", ".uniqueCodefield", function (e) {
            var key = window.event ? e.keyCode : e.which;
            var currentVal = $('.uniqueCodefield').val();
            if (key === 8 || key === 9 || key === 13 || key === 37 || key === 39 || key === 35 || key === 36 || key === 46) {
                return true;
            } else if (key === 13) {
                $('#newSongsSearch').validate();
                if ($('#newSongsSearch').valid()) {
                    return true;
                }
                return false;
                }
            else if ((key < 48 || key > 57) && (key < 93 || key > 105)) {
                return false;
            } else if (currentVal.length >= 10) {
                return false;
            } else {
                return true;
            }
        });

        @* Wire up the Search button click to perform an AJAXified search *@
        $(document).on("click", "#btnSearch", function (e) {
            e.preventDefault();

            // Only perform the search if the search criteria is valid.
            if (!$('#newSongsSearch').valid()) {
                return false;
            }

            $('.spinnerOverlay').removeClass('hide');

            var model = {
                SearchModel: {
                    WorkUniqueCode: $('#SongCode').val(),
                    SongTitle: $('#SongTitle').val(),
                    CatalogueUniqueCode: $('#CatalogueCode').val(),
                    CatalogueName: $('#CatalogueName').val(),
                    AccountUniqueCode: $('#AccountCode').val(),
                    AccountName: $('#AccountName').val()
                }
            };
            $.ajax({
                url: '@Url.Action("SearchNewSongs", "SongsManagement")',
                data: JSON.stringify(model),
                type: 'POST',
                cache: false,
                contentType: 'application/json',
                success: function (result) {
                    $('#tableContainer').html(result);
                    addBootstrapTooltips("#tableContainer");
                }
            });

            return false;
        });




         @* Wire up the Search button click to perform an AJAXified search *@
           $(document).on("click", "#btnSearch", function (e) {
               e.preventDefault();
               $('.spinnerOverlay').removeClass('hide');

               var model = {
                   SearchModel : {
                       Name: $('#ContractNameSearch').val(),
                       ContractType: $('#ContractTypeSearch').val(),
                       CreatedBy: $('#CreatedBySearch').val(),
                       DateFrom : $('#DateFromSearch').val(),
                       DateTo : $('#DateToSearch').val()
                   }
               };
               $.ajax({
                   url: '@Url.Action("SearchContracts", "ClientSetup")',
                   data: JSON.stringify(model),
                   type: 'POST',
                   cache: false,
                   contentType: 'application/json',
                   success: function (result) {
                       $('#tableContainer').html(result);
                       addBootstrapTooltips("#tableContainer");
                   }
               });

               return false;
        });
    </script>
    @Scripts.Render("~/bundles/searchusers-autosuggest")
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2"></script>
}


@section additionalStyles {
    @Styles.Render("~/plugins/datatables/media/css/cssDatatables")
}

<article class="row">
    <h1 class="pageTitle artistHeader fw200 mb20 mt10">@ViewBag.Title</h1>

    <div class="col-md-12">
        <div class="panel panel-visible">
            @Html.Partial("_NewSongsSearch", Model)
        </div>
    </div>

    <div class="col-md-12">
        <div class="panel panel-visible" id="tableContainer">
            @Html.Partial("_NewSongsList", Model)
        </div>
    </div>
</article>

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

Есть ли какой-либо код, который, по моему мнению, отсутствует, который бы упростил добавление ошибок в модальный режим?

Ответы [ 5 ]

0 голосов
/ 22 мая 2018

Хорошо, поэтому со всей информацией, которую вы нам дали, я чувствую уверенность в этом ответе.Я создал базовую страницу, на которой есть кнопка с id="click", которая запускает ajax-вызов к этому методу контроллера, аналогично вашему.

public ActionResult VerifyNewSongs()
{
    return Json(new JsonBaseModel
    {
        success = false,
        message = "oops",
        data = null,
        errors = new List<string>
        {
            $"Song already verified.",
            $"Song Title: title",
            $"Song Id: id"
        }
    });
}

Теперь это считается успешным ajax-вызовом, как и вашпоэтому, когда мы вернемся к представлению, оно окажется там.Я отредактировал раздел об успешности вашего вызова ajax с помощью кода, чтобы вывести предупреждение от SweetAlert2 (согласно нашему чату).Когда вы возвращаете success = false из контроллера, он перебирает ваш список ошибок и создает строку для передачи в оповещение.

$.ajax({
    url: '@Url.Action("VerifyNewSongs")',
    data: JSON.stringify(songs),
    type: 'POST',
    cache: false,
    contentType: 'application/json',
    success: function (result) {
        console.log(result);
        $('.spinnerOverlay').addClass('hide');
        if (result.success) {
            loadPartialPage($(".paginate_button.active a").attr("href"));
        }
        else{//MAIN CHANGE STARTS HERE
            var errorString = "";
            for (var i = 0; i < result.errors.length; i++) {
                errorString += result.errors[i] + "\n";
            }
            swal("Error!", errorString);
        }//MAIN CHANGE ENDS HERE
    },
    error: function (error) {
        $('.spinnerOverlay').addClass('hide');
    }
});

Основное различие между этой и вашей исходной функцией ajax заключается воператор else, когда result.success == false.Если вам нужно больше объяснений, дайте мне знать.

0 голосов
/ 22 мая 2018

попробуйте это:

return Json(new { error = your error, result = your result });
0 голосов
/ 22 мая 2018

Если я правильно читаю ваш вопрос, вы хотите добавить этот html:

<div class="alert alert-danger">
<strong>Danger!</strong> <p id='errorMessage'>This alert box could indicate a dangerous or potentially negative action.</p>
</div>

После этого вы можете получить свой идентификатор с помощью следующего кода и вставить сообщение об ошибке.

document.getElementById("errorMessage").innerHTML = "Put here your error variable";
0 голосов
/ 22 мая 2018

Вы можете сделать что-то вроде оборачивания кода бизнес-логики в вашем контроллере в try-catch, а затем ToString () в исключение и передать его обратно.

try
{
    //business logic

    //specific exception
    if (verifySongViewModels.NullOrEmpty())
    {
       throw new InvalidDataException();
    }
}
catch(Exception ex)
{
    // return error;
    return Json(new JsonBaseModel
    {
       success = false,
       message = InvalidRequest,
       data = null,
       error = ex.ToString()
    }
}

Затем, по вашему мнению, если приведенное выше представлениемодель, которую вы передаете обратно, имеет любую модель триггера ошибок.

0 голосов
/ 22 мая 2018

Способ, которым я обработал это в прошлом, состоит в том, чтобы написать небольшую часть перехвата ошибок в контроллере, который помещает их в ViewBag в виде списка ошибок.затем на главной странице просмотра есть некоторый JavaScript, который проверяет его на содержание при обновлении страницы.Я использовал Toastr вместо всплывающего окна начальной загрузки, чтобы отобразить ошибки, но я уверен, что всплывающее окно можно использовать также.

Это может быть излишним, но вы можете посмотреть SignalR .Он дает живые обновления вашей веб-страницы из вашего бэкэнда.

И в-третьих, делайте некоторые причудливые вещи с помощью ajax, чтобы пропинговать ошибки.

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