MVC - Display messages from the controller

Asked

Viewed 545 times

2

Within my MVC application we have several situations where, depending on the business rules of the function, several messages should be displayed to the user.

We are currently using the Jquery library "Toastr" to display messages to the user. The development is as follows:

1) Message settings (Messagemalerta.cshtml)

@helper MostrarMensagensAlerta(Alerta alerta)
{
    if (alerta != null)
    {
    <script>
        $(document).ready(function () {
            window.toastr.options.closeButton = '@alerta.MostrarBotaoFechar';
            window.toastr.options.newestOnTop = '@alerta.MostrarNoTopo';

            @foreach (Aperam.Biblioteca.Util.Base.Entidades.MensagemAlerta mensagem in alerta.MensagensAlerta)
            {
                string tipoAlerta = mensagem.TipoAlerta.ToString("F").ToLower();                
                @: var opcoes = { /* Adicione atributos específidos dos alertas Toastr aqui */ };

                @:opcoes.closeButton = true;
                @:opcoes.progressBar = true;
                @:opcoes.positionClass = "toast-top-right";

                if (mensagem.ManterAlerta)
                {
                    @:opcoes.timeOut = 0;
                    @:opcoes.extendedTimeout = 0;
                }
                else
                {
                    @:opcoes.timeOut = 10000;
                    @:opcoes.extendedTimeOut = 10000;
                }

                var texto = mensagem.Mensagem.Replace("\r\n", "<br /> ").Replace("\r", "<br /> ").Replace("\n", "<br /> ").Replace("'", "");
                @:window.toastr['@tipoAlerta']('@(new HtmlString(texto))', '@mensagem.Titulo', opcoes);
            }
        });
    </script>
    }
}

2) Partial view added to main page (_Message.cshtml):

@if (TempData.ContainsKey("Alerta"))
{
  Alerta alerta = TempData["Alerta"] as Alerta;
  @MensagemAlerta.MostrarMensagensAlerta(alerta);
}

3) Inside the master page, I added the div related to partial message view:

<div id="div-mensagens">
  @Html.Partial("_Mensagem")
</div>

4) Inside the controller, I have a method that adds messages via Tempdata:

public MensagemAlerta AdicionarMensagemAlerta(string mensagem, TipoAlerta tipoAlerta = TipoAlerta.Info)
    {
        string titulo = string.Empty;

        switch (tipoAlerta)
        {
            case TipoAlerta.Error:
                titulo = "Erro";
                break;
            case TipoAlerta.Info:
            case TipoAlerta.Success:
                titulo = "Informação";
                break;
            case TipoAlerta.Warning:
                titulo = "Alerta";
                break;
        }

        Alerta alerta = TempData["Alerta"] as Alerta;
        alerta = alerta ?? new Alerta();

        var mensagemAlerta = alerta.AdicionarMensagemAlerta(titulo, mensagem, tipoAlerta);
        TempData["Alerta"] = alerta;
        return mensagemAlerta;

    }

The inclusion and display of messages happens correctly when the request is via POST and the main page (_Layout.cshtml) is loaded again.

The problem is when calls are made via ajax and only partial view is loaded. Under these conditions, as the partial view "_Message.cshtml" is not reloaded, messages are not displayed.

Another problem is that my standard error handling also uses this function to display messages. This way, when an error occurs from an ajax call, the message is only displayed when the user reloads the full page.

A palliative solution that I’m using is, at the end of all ajax calls, to call the server by forcing the messages div to reload, as below:

 $(document).ajaxComplete(function(event, xhr, options) {
        if(options.url.toString().split('/')[2] != 'Mensagens')
            exibirMensagens();
    });

 function exibirMensagens() {
        $("#div-mensagens").load('@Url.Action("Mensagens")');
 }



public ActionResult Mensagens()
{
    return PartialView("~/Views/Shared/_Mensagem.cshtml");
}

I am not very satisfied with the solution that was given, as I am forcing a new call to the server without need.

I would like to share this problem with you to find the best way to treat this situation.

  • When you detect that it is by AJAX, include the partial view of the message in the partial view of the answer, does it not work ? Or better, because when you do by AJAX, instead of returning content not only returns data and does the processing in JS ? So you can return the result of the request via JSON along with the messages and let the JS turn the data into content and also display the messages correctly, which such ?

  • Another solution would be to completely separate the "messaging" service from your application, and turn it into a messaging/notification service as well as Stack Overflow and Facebook, which displays messages as they arrive (then your control would send the message to the service and the service to the user). You can do this easily with Signalr in C# or Socket.io in Node.js , but I don’t know if you want to take your application to this level, maybe it is to change a bike (human force, slower, not pollute) for a bike (CNH, fuel, IPVA, etc), understand the analogy ?

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.