开发者

Passing an optional object to all views

So, basically what I'd like is to do something like:

@if(Notification!=null){
     //perform javascript notification with @Notification.Text
 }

And I'd like to be able to do this on any view, so I will always have the option of specifying a notification object in my controller action, that, if defined, can be handled in the view.

My dream scenario is to allow this simply by creating the Notification开发者_如何学JAVA object somehow, and then just returning the view. Meaning, I wouldn't need to explicitly pass the Notification object to the model. Like so:

public ActionResult MyAction(){
    Notification n = new Notification("Text for javascript");
    return View();
}

I'm thinking, that there might be a way to do this with some ViewPage-inheritance? But I'm really unsure of how to go about this?

In an ideal world, I would also love to be able to "override" what to do. For example, if I in my 'top'-layout choose to perform a certain kind of jquery-notification if the notification object exists, but maybe in some other nested view would like to handle it differently, I'd like the option to override the top-layouts handling of the object.

I know this last thing might be a little utopian (I'm just starting out with MVC and Razor), but it would be cool :)


You could write a custom global action filter which will inject this information on all views. For example:

public class MyActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.Controller.ViewBag.Notification = new Notification("Text for javascript");                 
    }
}

and then register this filter in the RegisterGlobalFilters method of your Global.asax:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new MyActionFilterAttribute());
}

And then in your views:

@if(ViewBag.Notification != null) 
{
     //perform javascript notification with @ViewBag.Notification.Text
}


Use ViewBag for simple stuff like popup message.

public ActionResult Index()
{
    ViewBag.PopupMessage = "Hello!";
    return View();
}

and then in view (or layout page)

@if (ViewBag.PopupMessage != null)
{
    <div class="popup">@ViewBag.PopupMessage</div>
}

For more complicated stuff you will need to either create static class and save/read from HttpContext.Current.Items or override Controller and WebViewPage and save/read from ViewBag/ViewData.

Update:

public abstract class BaseController : Controller
{
    public const string NotificationKey = "_notification";

    protected string Notification
    {
        get
        {
            return ViewData[NotificationKey] as string;
        }
        set
        {
            ViewData[NotificationKey] = value;
        }
    }
}

public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
    protected string Notification
    {
        get
        {
            return ViewData[BaseController.NotificationKey] as string;
        }
    }
}

Views/Web.config

<pages pageBaseType="OverrideTest.Framework.BaseViewPage">

Usage:

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        Notification = "Hello from index!";

        return View();
    }
}

<div>Notification: @(Notification ?? "(null)")</div>

Or get test project here

Update 2: Check out this blog post for another way to do something similar.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜