drewwyatt
drewwyatt

Reputation: 6027

How can I keep static calls from caching in MVC?

I setup a Configuration model that stores a set of (essentially) Key => Value pairs that can be edited by the end user.

To make things easier I setup a static AppSettings class to make calling these easier throughout the app. (config values are never created or destroyed by the end user, only modified).

So what we have is (note - some of this has been removed for brevity):

Initializer

var configurations = new List<Configuration>
{
    new Configuration{ Key="CurrentGameID", Value="1" },
    new Configuration{ Key="AllowedStudentSpaces", Value="2" },
    new Configuration{ Key="WelcomeMessage", Value="Howdy, users" },
};
configurations.ForEach(c => context.Configurations.Add(c));
context.SaveChanges();

Helper

public static class AppSettings
{
    private static MyContext db = new MyContext();

    public static int CurrentGameID
    {
        get
        {
            var configuration = db.Configurations.FirstOrDefault(c => c.ID == (int)ConfigIDs.CurrentGame);
            return Convert.ToInt32(configuration.Value);
        }
    }

    public static int AllowedStudentSpaces
    {
        get
        {
            var configuration = db.Configurations.FirstOrDefault(c => c.ID == (int)ConfigIDs.AllowedStudentSpaces);
            return Convert.ToInt32(configuration.Value);
        }
    }

    public static string WelcomeMessage
    {
        get
        {
            var configuration = db.Configurations.FirstOrDefault(c => c.ID == (int)ConfigIDs.WelcomeMessage);
            return configuration.Value;
        }
    }
}

enum ConfigIDs
{
    CurrentGame = 1,
    AllowedStudentSpaces = 2,
    WelcomeMessage = 3
};

This should allow me to call whatever I need by doing something like:

<h1>@AppSettings.WelcomeMessage</p>

or

if(numSpaces < AppSettings.AllowedStudentSpaces)
{
 // Do work
}

That works great, but it appears that my app likes to cache the values returned by those calls when they are called using the AppSettings class. The updated values don't appear until I have cleared my session (by using a different browser or something). What causes that? Is there a way to circumvent it? Is there a better approach than what I am doing?

Upvotes: 0

Views: 76

Answers (2)

David Sherret
David Sherret

Reputation: 106810

You should set up a way to use a new DbContext with each page load. Right now the Configuration entities get attached once to the static DbContext's local and are not being reloaded from the database.

Upvotes: 1

Major
Major

Reputation: 6688

Use System.Web.Mvc.OutputCacheAttribute you can create a custom attribute like this:

public class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        Location = OutputCacheLocation.None;
        NoStore = true;
        Duration = 0;
        VaryByParam = "None";
    }
}

And apply it on your Controller which should not use cache.

Upvotes: 2

Related Questions