How to make ASP.NET MVC skins

Asked

Viewed 265 times

7

How would make skins in MVC? where the client(user) could choose the skin (would change CSS, html, images, etc)?

OBS¹: The Skin would be for all pages and each customer can have only 1 single skin. But I would have about 10 different skins. These skins can be just one css different or a whole different site.

NOTE²: Imagining that Only the Controller can be the same for different skins, Ex: public ActionResult MostrarProduto() will always return the same thing, only the view or _Layout may be different.

I imagine in three ways, but since I don’t have much experience in MVC I need to FACTS on the advantages and disadvantages of each, of course it may be that none of the 3 ways I imagine is the best.

1 - Filters in the controller:

[VerificarSkin]
public ActionResult MostrarProduto()
{

2 - Changing the Layout file by Controller or View

@{Layout = ViewBag.SkinAtual;}

3-Changing the View Folder [Video explaining this solution]

public ActionResult MostrarProduto()
{
    var skinAtual = "skin12";
     return View("../Views/" + skinAtual + "/Home/index.cshtml");

Solutions:

1 - Advantages: Code cleaning,

2 - Advantages: I take the same view for all skins mute only the layout, but then it can also be a disadvantage can not customize the view?

3 - Advantage: I can change everything, view and Layout, but it would take more work?

Scenario: Today I have 300 clients(users) where each one owns their site, these sites are shared from my tool, where he can choose the skins (which are from color changes to totally different layout)

  • Your idea and swap skins for user, page, by permission? Better, if choosing a skin will be the same for all pages, or I can choose one for each page, etc?

  • each customer would have only one skin that would be applied to all pages!

  • When you say customer you refer to each user who access the system or your system has multiple customers and each customer can have multiple users? I am asking these questions, because the context of your system, may change some factors. But, the third form seems to me unfeasible, so far.

  • good questions I will update the question. customer = user.

  • Which authentication method, Identity?

  • none, I identify the client by its url, so I know which site is which Clienteid is. The site is user anonymous, is a site and not an admin.

Show 1 more comment

1 answer

6


There is no way to say which is the best, because it will depend on what you will really need, I will explain it further below. So I will point out the strengths and weaknesses of these approaches.

First Form

The first way, as you said yourself, leaves the code much cleaner, and no redundancy, as it will create a filter to get the Skin necessary and return to the user. I believe it would look something like this:

 public class LayoutInjecterAttribute : ActionFilterAttribute
    {
        private readonly string _masterName;
        public LayoutInjecterAttribute(string masterName)
        {
            _masterName = masterName;
        }
    
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            var result = filterContext.Result as ViewResult;
            if (result != null)
            {
                result.MasterName = _masterName;
            }
        }
    }

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}

Source: How do I specify Different Layouts in the ASP.NET MVC 3 Razor Viewstart file?

Of course, applying your needs. The disadvantage of this method is that you will not be able to modify the Views with different information, namely Views will be the same, what will change will be the layout of the same.
Obs.: If that’s not a problem, I think the best solution to your case.

Second form

This form has the same disadvantages of the first, you will be able to change only the Layout, but still has another disadvantage, you will have to create the ViewBag each Action, as the life cycle of ViewBag is not used in Actions distinct. You can do OnActionExecuted or OnCreate controller, but still, you’ll have to do it in each controller, or in the View, but I’m sure you know that you don’t "should" do anything to her.

Third form

This is the way that will give you more work to implement, as you will have to replicate the code for each Skin that you own, and as you said you’ll have about 10... I guess you don’t want all this work.
However, if you need to change something, beyond the layout, in your Views, this will be the only way to get to do what you want.

Remembering also, that you will need to get the Skin in each View, and this may not be feasible, depending on the way you seek this Skin.

Conclusion (Staff)

Before concluding, may I remind you that when I speak of "changing nothing from View, I mean the code that’s on that View specific, but if it is something that can be shared for everyone, you will always have Shared _Layout for that reason.

Of the forms presented, I believe that the first one would be indicated. In addition to not having to rewrite the code, you will be able to manipulate each Action differently, if you wish. But if you need to change something in a View or else, the first two forms will not suit you.

But, depending on your context, nothing prevents you from using more than one form, using the third only where necessary.

  • your answer made me think, and I think unfortunately the first option will not be the best, because then I would have to have Equal Views for all skins and I believe I will not be able to customize both the site by _Layout and different css.

  • 4

    @Dorathoto I disagree. With HTML/CSS you can customize the entire site, the first option would only not serve if you have different behaviors. Visual and even show or not something, can be done by CSS only, if you want.

  • But like I said, there’s no way to be sure without knowing its context. So what you can do is just talk a little bit about each form presented.

  • 1

    The most correct form is, in fact, the first. Not only specify the fixed name in the attribute code, but also make a filter type whose layout is somehow associated with the user.

  • I think I’ll use the first way, but it prevents if you need a unique view or create a new one or use the third method.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.