Palantir
Palantir

Reputation: 24182

ASP.net MVC - request-scoped global variable

I have a value which I want to be vaild during a single request. I am not using Session, as this would make the value global for the entire navigation session.

So I have put thie value in a static field of a class. Great, but then I discovered that such fields are even more global, that is, they stay set for the entire application! This means that there could be random interaction among navigation sessions.

So the question is: is there a safe place I can put a global variable, which will be

Thanks Palantir

EDIT I'll elaborate. I have a piece of code in my master page, which I need to hide on certain conditions, of which I am aware in the controller only. I thought about setting a static variable in the controller, which then would be queried by the master page, but now I see there could be a better way...

Upvotes: 14

Views: 13161

Answers (6)

Dejan
Dejan

Reputation: 731

Did you look into the tempData that is attached to the controller class? it is a simple dictionary that preserves it's value through one single request.That would meant that your data can only be accessed in the controller but that should not be a problem.

public class MyController : Controller
{
  [AcceptVerbs(HttpVerbs.Get)]
  public ActionResult MyAction(string id)
  {
    this.TempData["Message"] = "YourData";
  }

  [AcceptVerbs(HttpVerbs.Post)]
  public ActionResult MyAction(string Id)
  {
    var myData = this.TempData["Message"];
  }
}

This works for me. I use it only to display warning messages and stuff like that.

Upvotes: 0

Richard
Richard

Reputation: 109005

TempData lasts until the next request as already noted.

But there are also two other dictionaries scoped to the single request.

  • {Controller,ViewPage}.ViewData
  • Context.Items

To communicate from controller to (master) page ViewData is probably the better choice.

Upvotes: 10

Keith
Keith

Reputation: 155692

This is relatively easy and there are a couple of ways that you can do it - depending on how your site works.

I'm interpreting your request as that you want a property or variable that exists for the duration of the request and is visible to the controller, model and master.

A static property is visible to the current application in ASP this means a load of users connecting at once, but not necessarily all of them. IIS will spawn new ASP applications as it needs to.

So the ways you can do this:

You can have a custom base class for your master page or a code-behind page (as all the WebForms stuff still works)

You can have a custom base class for your controllers.

You can get to one from the other, so:

void Page_Init( object sender, EventArgs e )
{
    var ctrl = this.ViewContext.Controller as MyBaseController;
    if ( ctrl != null )
    {
        MyLocalProp = ctrl.PropOnMyController;
    }
}

This will then be available in the controller and the master page on a per Request basis.

Upvotes: 1

Dylan Beattie
Dylan Beattie

Reputation: 54140

Use HttpContext.Items - a per-request cache store. Check out this article on 4guysfromrolla for more details.

It should work fine in ASP.NET MVC. You may wish to derive your master page from a base class (either via code-behind or using the Inherits directive) and have a protected method on the base class that inspects HttpContext.Items and returns, e.g. true/false depending whether you want to display the conditional code.

Upvotes: 25

Mathias F
Mathias F

Reputation: 15901

The common way to access data in a MasterPage that is set in Controller (Action) is via ViewData["TheDataKey"] = "SomeValue".

Upvotes: 1

D'Arcy Rittich
D'Arcy Rittich

Reputation: 171411

Two approaches come to mind:

  1. Create a base controller where you set this variable, and then have all your controllers inherit from that.
  2. Use TempData - the problem here being that it sticks around for the next request. But maybe knowing that, you can work around it by using a GUID key to determine that you are, in fact, getting a new value when you need it.

I would probably go with 1).

Upvotes: 2

Related Questions