从Controller向Boostrap Alert显示错误

时间:2018-05-22 13:07:10

标签: javascript c# jquery asp.net-mvc

我正在寻找一种方法来添加错误消息以显示错误。目前我在我的控制器中有这个来处理错误:

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 :(得分:1)

好的,所以你现在给我们的所有信息,我对这个答案充满信心。我创建了一个基本页面,其中只有一个带有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函数之间的主要区别在于result.success == false时的else语句中。如果您需要更多解释,请告诉我。

答案 1 :(得分:0)

我过去处理这个问题的方法是在控制器中写一些错误捕获器,将它们作为错误列表放入ViewBag中。然后在主视图页面上有一些javascript,在页面刷新时检查它的内容。我使用Toastr而不是bootstrap弹出窗口来显示错误,但我也确定弹出窗口也可以使用。

这可能有点矫枉过正,但您可以查看SignalR。它会从您的后端为您的网页提供实时更新。

第三,用ajax做一些奇特的事情来ping错误。

答案 2 :(得分:0)

如果我正确地阅读了您的问题,您想要添加此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>

之后,您可以使用以下代码获取您的ID并插入错误消息。

document.getElementById("errorMessage").innerHTML = "Put here your error variable";

答案 3 :(得分:0)

你可以做一些事情,比如在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()
    }
}

然后在您的视图中,如果您传回的上述视图模型有任何错误触发模型。

答案 4 :(得分:0)

试试这个:

return Json(new { error = your error, result = your result });