ASP.NET MVC 3中的Flash等效项

时间:2011-04-07 12:43:58

标签: asp.net-mvc

在轨道上的红宝石中有一个名为“flash”的功能,您可以将消息放入“flash”,重定向,并在下一个操作中显示该消息。

使用闪光灯的例子:

有一个控制器操作Account.ChangePassword。如果密码更改成功,ChangePassword将使用“密码更改成功”消息填充闪存,然后重定向到Account.Profile。在Account.Profile中,该消息可用,因此可以在配置文件页面中显示。

ASP.NET MVC 3中是否存在等效内容?

我知道我可以使用tempdata自己构建这个功能,但是MVC 3内置了什么?

8 个答案:

答案 0 :(得分:24)

恩迪,

我从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();
        }

    }
}

典型用法(控制器内部):

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);
    }
}

css也非常直接:

.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;
}

并在您的site.master

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

...享受

答案 1 :(得分:22)

不,TempData解决方案正是您所寻找的。

答案 2 :(得分:16)

我想升级Jim的答案,使用MVC 3的新辅助函数。

辅助函数可以轻松编写主要返回Html / javascript的函数,因此您不必使用字符串生成器或字符串连接。它可以产生更清晰的代码。

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;
        }
    }
}

然后创建ASP.NET App_Code文件夹并在那里创建一个.cshtml文件(可能是Flash.cshtml)并粘贴以下代码

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>
    }
}

这正在执行之前Flash功能正在做的事情,但是更加清晰。

除了你打电话的方式之外,其余的东西和吉姆的答案保持一致。而不是使用@ Html.Flash(),你需要像这样调用它:

@Flash.FlashMessage(TempData)

请注意,上面一行中的Flash是App_Code文件夹中.cshtml文件的名称。

希望它有所帮助。

答案 3 :(得分:16)

我重构了Imran的答案,以缩短代码:

<强>助手/ 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>
    }
}

从Twitter bootstrap借来的CSS代码

/* 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;
}

控制器内的用法:

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

布局(或其他cshtml文件)中的用法:

@Flash.FlashMessage(TempData)

答案 4 :(得分:13)

我知道有几种解决方案,但我一直在寻找一种纯粹的C#解决方案。我最喜欢@ TylerLong的解决方案,尽管我想为每种类型支持多条消息。另外,这是针对ASP.NET MVC4更新的,并且由于不需要更改配置文件,它也可能适用于其他版本的MVC框架。

功能

  • 纯C#解决方案
  • 使用视图助手,部分和扩展方法到Controller类
  • 应与多个版本的MVC框架兼容
  • 支持每种类型的多条消息
  • 没有配置更改您的Web.config文件

1)创建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
    {
        Info = 1,
        Success = 2,
        Warning = 3,
        Danger = 4
    }

    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)创建MvcProject/Views/Shared/_Flash.cshtml作为部分:

@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="alert alert-@type" role="alert">@message</p>
            }
        }
    }
    </div>
}

@FlashMessage(TempData)

3)在_Flash

中渲染MvcProject/Views/Shared/_Layout.cshtml部分
@Html.Partial("_Flash")

这将导致Flash消息包含在网页中。

4)在控制器中添加Flash消息

最后一块拼图在你的控制器中,现在应该有一个名为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 });
    }
}

答案 5 :(得分:2)

我在客户端上使用Cookie和JavaScript编写了一个用于ASP.NET的Rails样式Flash消息的示例,源代码和&amp;示例

<强>用法

添加对两个JavaScript文件的引用:jquery.cookie.js(标准jQuery cookie插件)和jQuery.flashMessage.js

在主布局视图中引用_Flash.cshtml部分。这将确定闪存消息的显示位置。

@Html.Partial("_Flash")

FlashMessageExtensions.cs静态扩展方法类添加到您的网站。

在您的MVC控制器中,只需使用.Success("message to show")以及Error上相应的WarningInformationActionResult扩展程序设置响应。请记住添加必要的using语句以使用上面的flash扩展类中的这些方法。

[HttpPost]
public ActionResult Create()
{
    return RedirectToAction("Index").Success("Message shown to user after redirect");
}

默认情况下,闪光信息会在3秒后淡出或者用户点击它。可以通过在配置JavaScript Flash插件时设置超时选项来配置淡出延迟,也可以通过将其设置为0来禁用淡出延迟。

答案 6 :(得分:0)

这是MvcContrib 2.0中一个非常需要的功能 - 我不确定它是否达到了3.0。我亲自在会话中将其保留在短时间内PRG =后重定向 - 获取。

答案 7 :(得分:0)

我认为这会让你开心。 https://github.com/khalidabuhakmeh/MvcFlash