C# 向视图传递消息
我使用在视图中显示确认消息等。我一直在努力寻找一种好方法,将消息从控制器传递到视图 我有一个使用TempData的janky feeling设置,它可以工作,但只有当我返回一个视图,而不是一个重定向,这是非常无用的 我最初打算将此功能添加到基本viewmodel,但C# 向视图传递消息,c#,asp.net-mvc,C#,Asp.net Mvc,我使用在视图中显示确认消息等。我一直在努力寻找一种好方法,将消息从控制器传递到视图 我有一个使用TempData的janky feeling设置,它可以工作,但只有当我返回一个视图,而不是一个重定向,这是非常无用的 我最初打算将此功能添加到基本viewmodel,但重定向到Action不支持传递viewmodels 我要么需要让TempData停留更长时间,要么使用完全不同的过程 我现在用的是: public class AlertifyMessages { public List<
重定向到Action
不支持传递viewmodels
我要么需要让TempData停留更长时间,要么使用完全不同的过程
我现在用的是:
public class AlertifyMessages
{
public List<AlertifyMessage> Messages { get; private set; } = new List<AlertifyMessage>();
public void Add(AlertifyType type, string message, string callbackUrl = null)
{
Messages.Add(new AlertifyMessage(type, message, callbackUrl));
}
}
public class AlertifyMessage
{
public AlertifyType Type { get; set; }
public string Message { get; set; }
public string CallbackUrl { get; set; }
public AlertifyMessage(AlertifyType type, string message, string callbackUrl)
{
Type = type;
Message = message;
CallbackUrl = callbackUrl;
}
}
public enum AlertifyType
{
Log,
Error,
Success
}
/// <summary>
/// Applies Alertify messages to TempData after action method runs
/// <para>Can only be used with <see cref="BaseController"/></para>
/// </summary>
public class AlertifyAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
BaseController bc = (BaseController)context.Controller;
bc.TempData["Alertify"] = bc.AlertifyMessages;
}
}
[Alertify]
public class BaseController : Controller
{
public BaseController()
{
AlertifyMessages = new AlertifyMessages();
}
public AlertifyMessages AlertifyMessages { get; set; }
}
编辑公认的答案是正确的,但为了避免大量重构,我只是在属性中添加了另一个过滤器,如下所示:
private const string alertify = "Alertify";
public override void OnActionExecuting(ActionExecutingContext context)
{
BaseController bc = (BaseController)context.Controller;
bc.Messages = (bc.TempData[alertify] == null) ? new AlertifyMessages() : (AlertifyMessages)bc.TempData[alertify];
// Faster? Better? Harder? Stronger?
//bc.Messages = (AlertifyMessages)bc.TempData[alertify] ?? new AlertifyMessages();
}
使用当前代码,在重定向过程中,
OnResultExecuting
将执行2次
假设你是这样做的
public ActionResult Save(SomeViewModel model)
{
AlertifyMessages.Add(AlertifyType.Success, "Yay!", Url.Action("Index"));
return RedirectToAction("Index");
}
public ActionResult Index()
{
return View();
}
在这里,当您从Save
操作方法返回结果时,它将执行AlertifyMessages筛选器的OnResultExecuting
方法,该方法读取控制器的AlertifyMessages
属性值并将其设置为TempData
现在,由于这是一个重定向响应,您的浏览器将发出一个新的GET请求,请求索引
操作,对于该操作方法,它还将执行OnResultExecuting
中的代码,并尝试读取AlertifyMessages
属性,并将其设置为TempData
。但是现在您的AlertifyMessages
没有任何值,因为您没有在Index
操作方法中设置该值记住Http是无状态的。这里的索引操作方法调用类似于一个全新的调用,该调用将创建控制器的一个新实例
解决方案是重新初始化AlertifyMessages
属性值。您可以从TempData中读取它
public ActionResult Index()
{
AlertifyMessages = TempData["Alertify"] as AlertifyMessages;
return View();
}
使用当前代码,在重定向过程中,
OnResultExecuting
将执行2次
假设你是这样做的
public ActionResult Save(SomeViewModel model)
{
AlertifyMessages.Add(AlertifyType.Success, "Yay!", Url.Action("Index"));
return RedirectToAction("Index");
}
public ActionResult Index()
{
return View();
}
在这里,当您从Save
操作方法返回结果时,它将执行AlertifyMessages筛选器的OnResultExecuting
方法,该方法读取控制器的AlertifyMessages
属性值并将其设置为TempData
现在,由于这是一个重定向响应,您的浏览器将发出一个新的GET请求,请求索引
操作,对于该操作方法,它还将执行OnResultExecuting
中的代码,并尝试读取AlertifyMessages
属性,并将其设置为TempData
。但是现在您的AlertifyMessages
没有任何值,因为您没有在Index
操作方法中设置该值记住Http是无状态的。这里的索引操作方法调用类似于一个全新的调用,该调用将创建控制器的一个新实例
解决方案是重新初始化AlertifyMessages
属性值。您可以从TempData中读取它
public ActionResult Index()
{
AlertifyMessages = TempData["Alertify"] as AlertifyMessages;
return View();
}
TempData应该可以重定向。你为什么认为它不起作用?你能分享ISSUE的代码吗?@Shyju如果我返回一个视图,它会工作,如果我返回一个重定向,它不会工作。我认为该属性正在重新分配tempdata条目,导致现有条目在被提供给视图之前丢失。我只是不知道怎么做。TempData应该可以重定向。你为什么认为它不起作用?你能分享ISSUE的代码吗?@Shyju如果我返回一个视图,它会工作,如果我返回一个重定向,它不会工作。我认为该属性正在重新分配tempdata条目,导致现有条目在被提供给视图之前丢失。我只是不知道怎么做。我认为解释重定向请求是一个新的控制器实例会有帮助。我认为解释重定向请求是一个新的控制器实例会有帮助。