Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

asp.net mvc - MVC Bootstrap Themes

I want to include theme support for the bootswatch themes in my MVC 5 app.

I want the users theme to be saved and loaded when they log in.

I have extended my user class to include the theme and can successfully set and save a theme on the edit user page.

public class User : IdentityUser
{       
public string BootstrapTheme {get;set;}
}

In the BootstrapTheme property I'll save the href attribute for the bootstrap css link. eg "~/Content/bootstrap.flatly.min.css"

The plan is to set the theme in the layout page.

<link href="~/Content/bootstrap.spacelab.min.css" rel="stylesheet" />

How can I do this without querying the database on every page load?

Being able to do something like <link href="@User.BootstrapTheme" rel="stylesheet" /> would be ideal.

Here is a link on how to save it for one page using localstorage http://wdtz.org/bootswatch-theme-selector.html

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You should store theme name/url as a claim on the user, not as part of the User class:

await userManager.AddClaimAsync(user.Id, new Claim("MyApp:ThemeUrl", "~/Content/bootstrap.flatly.min.css"));

When user is logged in, this claim is added to the cookie and you can access it through extension method:

public static String GetThemeUrl(this ClaimsPrincipal principal)
{
    var themeClaim = principal.Claims.FirstOrDefault(c => c.Type == "MyApp:ThemeUrl");
    if (themeClaim != null)
    {
        return themeClaim.Value;
    }
    // return default theme url if no claim is set
    return "path/to/default/theme";
}

and in your view you would access theme url like this:

<link href="@ClaimsPrincipal.Current.GetThemeUrl()" rel="stylesheet" />

Claims on principal are available in the cookie, so no extra DB hits required.

As an alternative you can persist user BootstrapTheme as you already have done, but when user is logging in, add this theme as a claim to the identity:

public async Task SignInAsync(IAuthenticationManager authenticationManager, ApplicationUser applicationUser, bool isPersistent)
{
    authenticationManager.SignOut(
        DefaultAuthenticationTypes.ExternalCookie,
        DefaultAuthenticationTypes.ApplicationCookie);

    var identity = await this.CreateIdentityAsync(applicationUser, DefaultAuthenticationTypes.ApplicationCookie);

    identity.AddClaim(new Claim("MyApp:ThemeUrl", applicationUser.BootstrapTheme));

    authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

And then access the claim in the view via above-mentioned extension method. I've blogged recently about similar scenario - you can have a look there for a bit more insight how claims work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...