1

I'm trying to change the user's current culture via AJAX POST:

$.ajax({
    type: 'POST',
    url: '/Account/SetDefaultCulture',
    data: data,
    dataType: 'JSON',
    success: function (result) {
      location.reload(true);
    }
  });

With this controller method:

private readonly AspEntities db = new AspEntities();
[HttpPost]
    public JsonResult SetDefaultCulture(string userName, string culture)
    {
      if (!userName.IsNullOrEmpty())
      {
        var user = (from a in _db.AspNetUsers
                where a.UserName == userName
                select a).FirstOrDefault();
        if (user != null)
        {
          user.Culture = culture;
          db.SaveChanges();
          Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
          return Json(new { culture, success = true });
        }
      }

      return Json(new {culture, success = false});
    }

If I step through while debugging, I can see the database record update right after db.SaveChanges() is called.

The problem is the application/website doesn't update the user's Culture until AFTER I change some code in the Controller, and then build the project again. It's almost as if the Culture is being cached within the application or something.

I must be missing something. Is this common? Has anyone encountered this?

EDIT

I am using a Utility method to check the current user's culture:

public static CultureInfo GetCulture()
{
  var userId = HttpContext.Current.User.Identity.GetUserId();
  var user = (from a in _db.AspNetUsers
              where a.Id == userId
              select a).FirstOrDefault();
  var culture = "en-CA";

  if (user != null)
  {
    if (!user.Culture.IsNullOrEmpty())
    {
      culture = user.Culture;
    }
  }

  return new CultureInfo(culture);
}

Within a Filter which runs on every page hit:

public class CheckCultureAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    HttpContext ctx = HttpContext.Current;
    string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower().Trim();
    string actionName = filterContext.ActionDescriptor.ActionName.ToLower().Trim();

    //Set Culture
    var culture = (ctx.User != null) ? Utilities.GetCulture() : new CultureInfo("en-CA");
    Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = culture;

    ...
  }
}

If I start the debugger and step through this filter, the GetCulture() method returns the non-updated value (which does not match the value that has been updated in the Database)

projeqht
  • 3,160
  • 3
  • 18
  • 32
  • Are you pulling the user's current culture from the database on every page hit, or are you caching it in the session variable (or user cookie?) – Robert McKee Mar 12 '15 at 16:19
  • From the database on every page hit. I haven't set up the cookie yet although that is next on my to do list hehe – projeqht Mar 12 '15 at 16:20
  • This line `Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);` isn't going to do much as the Thread is just about to end at the next statement (return). As far as I can see the problem isn't with the code you have provided. – Robert McKee Mar 12 '15 at 16:27
  • @RobertMcKee I just updated the Question with my Filter method which runs every time the page loads. I just tried setting the Culture before the `return` statement in `SetDefaultCulture` as a test, although I know it would be overridden by whatever the Filter method sets. – projeqht Mar 12 '15 at 16:29
  • The user data is being persisted via cookie or session. It's not looking up the user on every page hit. And since you are persisting the culture data in teh the AspNetUsers table, most likely it is being persisted in cookie or session as well. – Robert McKee Mar 12 '15 at 16:34
  • @RobertMcKee even when `GetCulture()` does a fresh linq query to AspNetUsers table every time? – projeqht Mar 12 '15 at 16:35
  • Sorry, didn't see that. However, after updating the user, try using a different browser that the one you used to update the culture (Chrome, IE, Firefox) and go to your page and see if it picks up the new culture immediately. – Robert McKee Mar 12 '15 at 16:39
  • @RobertMcKee I thought you were on to something. I checked Firefox and Safari after changing the Culture in Chrome. They ALL showed the wrong, non-updated Culture. This means it's not being cached in the browser? – projeqht Mar 12 '15 at 16:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72859/discussion-between-projeqht-and-robert-mckee). – projeqht Mar 12 '15 at 16:43
  • @RobertMcKee I ended using a cookie to determine the Culture, with it falling back on the LINQ query. This works, but if for some reason the cookie is present, the original LINQ query that was returning the wrong value has not been fixed yet. Thanks for your help, again. – projeqht Mar 12 '15 at 19:57

4 Answers4

1

Seems like EF is not tracking your changes. Try something like this,

db.Entry(AspNetUsers).State = EntityState.Modified;

before: db.SaveChanges();

Also you are quering _db context while i can see that your context is private readonly AspEntities db = new AspEntities();

Which hints ur context is not set right? Don't know if I am correct but do check your context.

Hasta Tamang
  • 2,205
  • 1
  • 18
  • 17
0

Cant comment yet, but have you checked this other stack overflow question

According to that link it seems that the action filter is already too late to set the culture for the request.

Community
  • 1
  • 1
0

Check to see if you are referencing data from an already instantiated database context (AspEntities db) in the controller that is supposed to produce the updates. The readonly modifier will prevent changes after declaration, unless you are always creating a new controller object.

Ken
  • 36
  • 4
-1

I think you first have to attach the user to your DbContext.

db.AspNetUsers.Attach(user);

Then call save changes. Every time I have run into issues updating my DB, this has been the cause. I do believe you have to refresh the page after this update too.

JRT
  • 34
  • 1