Within my MVC application we have several situations in which, depending on the business rules of the function, several messages should be displayed to the user.
We are currently using the Jquery "Toastr" library to display messages to the user. The development is as follows:
1) Configuring Message Settings (Alert Message.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 the main page (_Message.cshtml):
@if (TempData.ContainsKey("Alerta"))
{
Alerta alerta = TempData["Alerta"] as Alerta;
@MensagemAlerta.MostrarMensagensAlerta(alerta);
}
3) Within the master page, I added the div related to partial view of messages:
<div id="div-mensagens">
@Html.Partial("_Mensagem")
</div>
4) Inside the controller, I have a method that adds the 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 visualization of the 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 the partial view is loaded. In these conditions, since the partial view "_Message.cshtml" is not reloaded, the messages are not displayed.
Another problem is that my standard error handling also uses this function to display the messages. This way, when an error occurs from an ajax call, the message is only displayed when the user reloads the entire page.
A palliative solution that I am using is, at the end of every ajax call, to make a new call to the server forcing the message div reload, as follows:
$(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'm not very happy with the solution that was given, as I'm forcing a new call to the server unnecessarily.
I would like to share this problem with you to find the best way to handle this situation.