Home > Back-end >  Display a modal dialog with an error message when the error is generated in the MVC controller
Display a modal dialog with an error message when the error is generated in the MVC controller

Time:11-04

ASP.NET MVC newbie here. I inherited an old MVC 5 application that I have to fix and extend with some new functionality. The people that worked on it left the company a long time ago and I cannot go and ask for clarifications. Essentially, they have never implemented a way to display error messages when the error happens in the controller (written in C#). There are error messages being displayed but those are only for errors that are caught in the Javascript code that is part of the scripts, inside the views ("*.cshtml" files). The developers used BootstrapDialogs and I have plenty of examples on how those can be tailored to look in a particular way (background colors, buttons available, etc.).

One of the features I had to implement is to transfer the control to a hosted payment page (HPP) that belongs to the PSP (Payment Service Provider). Once the payment is processed, the HPP posts back the result to an HTTP URL that I provide. Essentially, that's just a method in my controller that is listening to incoming HTTP POSTs. Now, when the response from the HPP is coming, I may see that the payment request has been approved or declined. If it was declined, I have access to the reason for the decline and this is what I need to display to the customer.

I found a couple of solutions here on SO, where I can set a specific property in the ViewBag to the complete error message I want to display. I've seen ways in which the view may have a that would display my error message. That is not really what I want to do. For the sake of consistency, I would like to display one of these modal BootstrapDialogs and show the message with an OK button that would close the modal dialog.

What is the pattern to do so? In my controller, at the end of the method that handles the incoming HTTP POST (I think this method is called a webhook) I can set the ViewBag property and return the view, but I don't really know what code I need to write in the view to cause that ViewBag property to be displayed every time it is not null - here I need to add that the same view is displayed in several situations, as it contains the list of payments that were made. When the payment request is approved and there is no error, my webhook method updates the model with all the payments, (including the newest one that was just processed) and returns the view that will use the model to display all the information in a proper way.

TIA, Ed

EDIT 1: In my Index.cshtml file, in the script section, I have the following Javascript function that is used to display errors that are detected in the Javascript code:

    function displayErrorMessage(errorMessageToDisplay) {
     BootstrapDialog.show({
        title: 'Error',
        type: BootstrapDialog.TYPE_DANGER,
        message: errorMessageToDisplay,
        buttons: [
           {
              label: 'OK',
              action: function (dialogItself) {
                 dialogItself.close();
              }
           }]
     });

     return false;
    };

As I mentioned, this uses BootstrapDialog which is a modal window that looks nice and can be dismissed by the user after the message is read.

I need to call this function and pass in the message that is sent to the View via the ViewBag. In my controller, before the View is returned, I check if the payment was successful. If it wasn't, I build an error message with the details sent to me by the Payment Service Provider. The error message built, if not null, get stored in the ViewBag this way:

if(!string.IsNullOrEmpty(errorMessageToDisplay))
{
   ViewBag.ErrorMessageToDisplay = errorMessageToDisplay;
}

return View();

So now I need a way in the View to call my function that displays the error message every time my ViewBag has an error message to display.

EDIT 2: I can use an area on my View to show the error message, like this:

<div style="float: right; text-align: left; display:inline;
    margin-right:100px;">
  @if (!string.IsNullOrEmpty(ViewBag.ErrorMessageToDisplay))
  {
     <div style="font-weight: bold; color: yellow;
          background-color: red;
          margin: 20px 0 0 0;">@ViewBag.ErrorMessageToDisplay</div>
  }
</div>

This works fine, but the thing that I don't like is that the message will stay on until the user gets to refresh the page in some sort. For consistency, I would like to use my BootstrapDialogs.

EDIT 3: I ended up accepting Farid's solution. From his solution, I only used the "$(window).on('load', function ()", as in the following sequence:

<script type="text/javascript">

$(function () {

   var errorMessageToDisplay = '@(ViewBag.ErrorMessageToDisplay)';

   $(window).on('load', function () {
      if (errorMessageToDisplay) {
         displayErrorMessage(errorMessageToDisplay);
      }
   });
});

function displayErrorMessage(errorMessageToDisplay) {
   BootstrapDialog.show({
      title: 'Error',
      type: BootstrapDialog.TYPE_DANGER,
      message: errorMessageToDisplay,
      buttons: [
         {
            label: 'OK',
            action: function (dialogItself) {
               dialogItself.close();
            }
         }
      ]
   });

   return false;
 };

 </script>

With that in place, my modal form is always displayed, when the View is returned and the error message to display is different than null.

Thanks, Ed

CodePudding user response:

I don't really know what code I need to write in the view to cause that ViewBag property to be displayed every time it is not null - here I need to add that the same view is displayed in several situations, as it contains the list of payments that were made

Well, there are several ways available to handle this kind of scenario. You could use ViewBag and TempData to display the relevant information to the user based on the scenario. Here, I am sharing the basic example for you.

In my example, I am declining the transaction above $500 to simulate the scenario consequently will display to "insufficient balance" message to user using modal.

Controller:

    [IgnoreAntiforgeryToken]
    [HttpPost]
    public ActionResult PostPaymetInfo(UserModel paymentModel)
    {
        if (paymentModel.UserPurchaseinfo.PurchaseAmount > 500)
        {
         
            TempData["UserMessage"] = "Insufficient balance, Transaction Declined!";
            return RedirectToAction("Index");
        }
        else
        {
            TempData["UserMessage"] = "Transaction Successful!";
            return RedirectToAction("Index");
        }
       
     
    }

Note: Here while submitting the transaction request, I am checking the amount and if that's above $500 then I am generating the error message and passing to the message to index using TempData["UserMessage"] and in Index action finally binding it into the ViewBag.UserMessage = userMessage finally passing the message to the view using ViewBag as you can see below:

public ActionResult Index()
        {
            var userMessage = TempData["UserMessage"]?.ToString();
            ViewBag.UserMessage = userMessage;

            return View();
        }

View:

@if (@ViewBag.UserMessage != null)
{
    <div  tabindex="-1" id="modal3"
     data-keyboard="false" data-backdrop="static">
        <div >
            <div >
                <div >
                </div>
                <div >
                </div>
                <div >
                    <button type="button" id="btnHideModal" >
                        Close
                    </button>
                </div>
            </div>
        </div>
    </div>

    @section Scripts{

    <script type="text/javascript">

        const modal = document.getElementById("modal3")
        $(window).on('load', function () {
            console.log(modal);

            modal.style.display = "block";
            $("#modal3").find(".modal-header").html('@ViewBag.UserMessage');
            $("#modal3").find(".modal-body").html('@ViewBag.UserMessage');
            $("#modal3").modal('show');
        });
        function closeModal() {
            modal.style.display = "none";

        }
        $("#btnHideModal").click(function () {
            $("#modal3").modal('hide');
        });
    </script>

    }
}

Note: Here when the transaction will approved we will display an approval message and when transaction will be declined will display the warning message.

Output:

enter image description here

Note: I am binding the same message both in modal body and modal header, you can modify as per your requirement. This is one of the way you could handle, we can use full JavaScript, we even can use TempData["UserMessage"] as well.

  • Related