33 votes

Équivalent Flash dans ASP.NET MVC 3

Il y a une fonctionnalité appelée "flash" en ruby on rails où vous pouvez mettre un message dans 'flash', redirection, et le message est disponible dans la prochaine action.

Exemple de l'utilisation de flash:

Il y a une action de contrôleur de Compte.ChangePassword. Si le changement de mot de passe est réussie, ChangePassword remplira flash avec un message "changement de Mot de passe réussie", puis redirige vers Compte.De profil. En Compte.De profil, le message est disponible de sorte qu'il peut être affiché dans la page de profil.

Est-il quelque chose d'équivalent dans ASP.NET MVC 3?

Je sais que je peux construire cette fonction moi-même à l'aide de tempdata comme ça, mais ne MVC 3, ont quelque chose de construit dans?

24voto

jim tollan Points 12995

Endy,

J'ai «emprunté» cela à la série tekpub:

 namespace System.Web.Mvc {
    public static class FlashHelpers {

        public static void FlashInfo(this Controller controller,string message) {
            controller.TempData["info"] = message;
        }
        public static void FlashWarning(this Controller controller, string message) {
            controller.TempData["warning"] = message;
        }
        public static void FlashError(this Controller controller, string message) {
            controller.TempData["error"] = message;
        }

        public static string Flash(this HtmlHelper helper) {

            var message = "";
            var className = "";
            if (helper.ViewContext.TempData["info"] != null) {
                message =helper.ViewContext.TempData["info"].ToString();
                className = "info";
            } else if (helper.ViewContext.TempData["warning"] != null) {
                message = helper.ViewContext.TempData["warning"].ToString();
                className = "warning";
            } else if (helper.ViewContext.TempData["error"] != null) {
                message = helper.ViewContext.TempData["error"].ToString();
                className = "error";
            }
            var sb = new StringBuilder();
            if (!String.IsNullOrEmpty(message)) {
                sb.AppendLine("<script>");
                sb.AppendLine("$(document).ready(function() {");
                //sb.AppendFormat("$('#flash').html('{0}');", message);
                sb.AppendFormat("$('#flash').html('{0}');", HttpUtility.HtmlEncode(message));
                sb.AppendFormat("$('#flash').toggleClass('{0}');", className);
                sb.AppendLine("$('#flash').slideDown('slow');");
                sb.AppendLine("$('#flash').click(function(){$('#flash').toggle('highlight')});");
                sb.AppendLine("});");
                sb.AppendLine("</script>");
            }
            return sb.ToString();
        }

    }
}
 

utilisation typique (à l'intérieur du contrôleur):

 public ActionResult Delete(int id, FormCollection collection)
{
    var item = _session.Single<UserActions>(x=>x.ID == id);
    try
    {
        _session.Delete<UserActions>(item);
        _session.CommitChanges();
        this.FlashInfo("UserAction deleted ...");
        return RedirectToAction("Index");
    }
    catch
    {
        this.FlashError("There was an error deleting this record");
        return View("Edit",item);
    }
}
 

le css est assez simple aussi:

 .info
{
    background-color: #CCFFCC;
    border-top: 1px solid #FFCC66;
    border-bottom: 4px solid #FFCC66;
    padding: 6px;
    font-family: helvetica;
    font-size: 1.1em;
    text-align: center;
    border-top-color: #006600;
    border-bottom-color: #006600;
    font-weight: bold;
    color: #339933;
    cursor:pointer;
}
.warning
{
    background-color: #FFFF99;
    border-top: 1px solid #FFCC66;
    border-bottom: 4px solid #FFCC66;
    padding: 6px;
    font-family: helvetica;
    font-size: 0.9em;
    text-align: center;
    border-top-color: #CC9900;
    border-bottom-color: #CC9900;
    font-weight: bold;
    color: #663300;
    cursor:pointer;
}
.error
{
    background-color: #FFCC99;
    border-top: 1px solid #FFCC66;
    border-bottom: 4px solid #FFCC66;
    padding: 4px;
    font-family: helvetica;
    font-size: 1.1em;
    text-align: center;
    border-top-color: #800000;
    border-bottom-color: #800000;
    font-weight: bold;
    color: #990000;
    cursor:pointer;
}
 

et dans votre site.master

 <%=Html.Flash() %>
<body>
    <div id="flash" style="display: none">
    </div>
.... etc
</body>
 

prendre plaisir...

22voto

Swaff Points 3608

Non, la solution TempData est ce que vous recherchez.

17voto

Tyler Long Points 1216

J'ai refactorisé la réponse d'Imran pour raccourcir le code:

Helpers / FlashHelper.cs

 namespace System.Web.Mvc
{
    public enum FlashEnum
    {
        Success = 1,
        Info = 2,
        Warning = 3,
        Error = 4
    }
    public static class FlashHelper
    {
        public static void Flash(this Controller controller, string message, 
            FlashEnum type = FlashEnum.Success)
        {
            controller.TempData[string.Format("flash-{0}", 
                type.ToString().ToLower())] = message;
        }
    }
}
 

App_Code / Flash.cshtml

 @helper FlashMessage(System.Web.Mvc.TempDataDictionary tempData)
{
    var flash = tempData.Where(item => item.Key.StartsWith("flash-"))
        .Select(item => 
            new { Message = item.Value, ClassName = item.Key }).FirstOrDefault();
    if (flash != null)
    {
    <script type="text/javascript">
        $(function () {
            var $flash = $('<div id="flash" style="display:none;">');
            $flash.html('@flash.Message');
            $flash.toggleClass('flash');
            $flash.toggleClass('@flash.ClassName');
            $('body').prepend($flash);
            $flash.slideDown('slow');
            $flash.click(function () { $(this).slideToggle('highlight'); });
        });
    </script>
    }
}
 

Code CSS emprunté à Twitter Bootstrap

 /* Styles for flash messages
-----------------------------------------------------------*/

.flash
{
    padding: 8px 35px 8px 14px;
    margin-bottom: 18px;
    border: 1px solid;
}

.flash-success
{
    color: #468847;
    background-color: #DFF0D8;
    border-color: #D6E9C6;
}

.flash-info
{
    color: #3A87AD;
    background-color: #D9EDF7;
    border-color: #BCE8F1;
}

.flash-warning
{
    color: #C09853;
    background-color: #FCF8E3;
    border-color: #FBEED5;
}

.flash-error
{
    color: #B94A48;
    background-color: #F2DEDE;
    border-color: #EED3D7;
}
 

utilisation à l'intérieur du contrôleur:

 this.Flash("Huston, we have an error!!", FlashEnum.Error);
 

utilisation à l'intérieur de la mise en page (ou autre fichier cshtml):

 @Flash.FlashMessage(TempData)
 

16voto

Imran Rashid Points 686

Je veux mettre à jour Jim, en réponse à l'utilisation de MVC 3 nouvelles fonctions d'assistance.

Fonctions d'assistance de rendre plus facile l'écriture de fonctions que c'est principalement le retour Html/javascript, de sorte que vous n'avez pas à utiliser le générateur de chaîne ou de concaténation de chaîne. Il en résulte beaucoup plus propre code.

FlashHelpers.cs :

namespace System.Web.Mvc {

    public static class FlashHelpers {

        public static void FlashInfo(this Controller controller,string message) {
            controller.TempData["info"] = message;
        }
        public static void FlashWarning(this Controller controller, string message) {
            controller.TempData["warning"] = message;
        }
        public static void FlashError(this Controller controller, string message) {
            controller.TempData["error"] = message;
        }
    }
}

Ensuite, vous créez le ASP.NET dossier App_Code et créer un .cshtml fichier (Flash.cshtml probablement) et le coller dans le code suivant

App_Code/Flash.cshtml :

@helper FlashMessage(TempDataDictionary tempData){
    var message = "";
    var className = "";
    if (tempData["info"] != null)
    {
        message = tempData["info"].ToString();
        className = "flashInfo";
    }
    else if (tempData["warning"] != null)
    {
        message = tempData["warning"].ToString();
        className = "flashWarning";
    }
    else if (tempData["error"] != null)
    {
        message = tempData["error"].ToString();
        className = "flashError";
    }
    if (!String.IsNullOrEmpty(message))
    {
        <script type="text/javascript">
            $(document).ready(function() {
            $('#flash').html('@message');
            $('#flash').toggleClass('@className');
            $('#flash').slideDown('slow');
            $('#flash').click(function(){$('#flash').toggle('highlight')});
            });
        </script>
    }
}

C'est en faisant ce que la fonction de Flash a été fait avant, mais en beaucoup plus propre chemin.

Reste des choses restent les mêmes que dans sa réponse, sauf de la façon dont vous l'appelez. Au lieu d'utiliser @Html.Flash(), vous avez besoin de l'appeler comme ceci:

@Flash.FlashMessage(TempData)

Veuillez noter que le Flash dans la ligne ci-dessus est le nom de la .cshtml fichier dans le dossier App_Code.

Espérons que cela aide.

13voto

Greg Burghardt Points 2846

Je sais qu'il y a plusieurs solutions, mais je cherchais une pure solution C#. J'aime @TylerLong la solution la meilleure, mais je voulais en charge plusieurs messages pour chaque type. De Plus, il est mis à jour pour ASP.NET MVC4, et il n'y a pas de fichier de config changements nécessaires, il serait sans doute travailler pour les autres versions du framework MVC ainsi.

Caractéristiques

  • Pure C# solution
  • Utilise les aides de vue, les partiels, et d'une extension de la méthode à la classe Controller
  • Doit être compatible avec plusieurs versions du framework MVC
  • Prend en charge plusieurs messages par type
  • Pas de config modifications à votre site Web.les fichiers de configuration

1) Créez MvcProject/Helpers/FlashHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcProject.Helpers
{
    public enum FlashLevel
    {
        Primary = 1,
        Success = 2,
        Info = 3,
        Warning = 4,
        Danger = 5,
        Error = 6
    }

    public static class FlashHelper
    {
        public static void Flash(this Controller controller, string message, FlashLevel level)
        {
            IList<string> messages = null;
            string key = String.Format("flash-{0}", level.ToString().ToLower());

            messages = (controller.TempData.ContainsKey(key))
                ? (IList<string>)controller.TempData[key]
                : new List<string>();

            messages.Add(message);

            controller.TempData[key] = messages;
        }
    }
}

2) Créez MvcProject/Views/Shared/_Flash.cshtml Partielle:

@helper FlashMessage(System.Web.Mvc.TempDataDictionary tempData)
{
    <div class="flash-messages">
    @foreach (FlashLevel level in (FlashLevel[]) Enum.GetValues(typeof(FlashLevel)))
    {
        string type = level.ToString().ToLower();
        string key = "flash-" + type;

        if (tempData.ContainsKey(key))
        {
            IList<string> messages = (IList<string>)tempData[key];

            foreach (string message in messages)
            {
                <p class="bg-@type">@message</p>
            }
        }
    }
    </div>
}

@FlashMessage(TempData)

3) Rendre l' _Flash partiel en MvcProject/Views/Shared/_Layout.cshtml

@Html.Partial("_Flash")

Ce sera la cause de la flash les messages à être inclus dans la page web.

4) Ajouter des messages flash dans vos Contrôleurs

La dernière pièce du puzzle est dans vos Contrôleurs, qui devrait maintenant avoir une méthode appelée Flash(string message, FlashLevel level):

using MvcProject.Helpers;

public class FoosController : Controller
{
    public ActionResult Edit(int id, FooViewModel model)
    {
        // ...
        this.Flash("Foo was updated", FlashLevel.Success);
        this.Flash("Another success message!", FlashLevel.Success);
        this.Flash("But there was a slight problem...", FlashLevel.Warning);

        return RedirectToAction("Edit", new { id = id });
    }
}

Twitter Bootstrap CSS Intégration

Pour ceux d'entre vous avec Bootstrap CSS, vous aurez besoin d'inclure l'extrait suivant de CSS quelque part:

.flash-messages p
{
    padding: .5em;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X