Подтвердить что ты не робот

Эквивалент Flash в ASP.NET MVC 3

В рубинах на рельсах есть функция, называемая "flash", где вы можете поместить сообщение в "flash", перенаправить, и сообщение доступно в следующем действии.

Пример использования вспышки:

Существует действие контроллера Account.ChangePassword. Если смена пароля будет успешной, ChangePassword заполнит флэш с сообщением "Успешное изменение пароля", а затем перенаправит его в Account.Profile. В Account.Profile сообщение доступно, чтобы оно отображалось на странице профиля.

Есть ли что-то эквивалентное в ASP.NET MVC 3?

Я знаю, что я могу самостоятельно создать эту функцию, используя tempdata, но имеет ли MVC 3 что-то встроенное?

4b9b3361

Ответ 1

Нет, решение TempData - это то, что вы ищете.

Ответ 2

Endy,

Я "заимствовал" это из серии 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;
}

и в вашем сайте .master

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

наслаждаться...

Ответ 3

Я хочу обновить 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 в указанной выше строке - это имя файла .cshtml в папке App_Code.

Надеюсь, что это поможет.

Ответ 4

Я реорганизовал ответ Имрана, чтобы сделать код короче:

хелперы /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>
    }
}

CSS-код, заимствованный из бутстрапа twitter

/* 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)

Ответ 5

Я знаю, что есть несколько решений, но я искал чистое решение С#. Мне нравится @TylerLong решение лучшее, хотя я хотел бы поддерживать несколько сообщений для каждого типа. Кроме того, это обновление для ASP.NET MVC4, и, поскольку нет необходимости в изменении файла конфигурации, он, вероятно, будет работать и для других версий среды MVC.

Особенности

  • Решение Pure С#
  • Использует элементы справки, частичные части и метод расширения класса 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 [email protected]" role="alert">@message</p>
            }
        }
    }
    </div>
}

@FlashMessage(TempData)

3) Отметьте _Flash частичное в MvcProject/Views/Shared/_Layout.cshtml

@Html.Partial("_Flash")

Это приведет к включению флэш-сообщений на веб-странице.

4) Добавьте флеш-сообщения в свои контроллеры

Последний фрагмент головоломки находится в ваших контроллерах, теперь у него должен быть метод 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 });
    }
}

Ответ 6

Я написал пример флеш-сообщений Rails для ASP.NET с использованием файлов cookie и JavaScript на клиенте с исходным кодом и примером.

Использование

Добавьте ссылку на два файла JavaScript: jquery.cookie.js (стандартный плагин jQuery cookie) и jQuery.flashMessage.js

Ссылка части _Flash.cshtml в пределах вашего основного вида макета. Это определит, где появятся флэш-сообщения.

@Html.Partial("_Flash")

Добавьте класс статического метода расширения FlashMessageExtensions.cs на ваш сайт.

В ваших MVC-контроллерах просто используйте .Success("message to show") и соответствующие методы расширения Error, Warning или Information на ActionResult, чтобы установить флэш файл cookie в ответ. Не забудьте добавить необходимый оператор using, чтобы использовать эти методы из класса расширения Flash выше.

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

По умолчанию флэш-сообщение будет исчезать через 3 секунды или если пользователь нажмет на него. Задержка затухания настраивается путем установки параметра таймаута при настройке флеш-модуля JavaScript или может быть отключена при установке 0.

Ответ 7

Это запрошенная функция, которая была в MvcContrib 2.0 - я не уверен, достиг ли она 3.0. Я лично храню его в сеансе на короткий период, когда я делаю PRG= Post-Redirect-Get.