2

I'm using .Net Framework 4.8. I need an option in my web app to be able to override default views (just cshtml files) for each customer we have. For example consider that I have a view in folder views/account/Login.cshtml. I want to load a customized version if exists from /Views/Overrides/[MyCustomerName]/Account/Login.cshtml. How can I achieve that?

Asma Jam
  • 23
  • 3
  • What kinds of customisation do you have in-mind? If it's just static content (HTML/CSS/JS) then can't you store that in your database? – Dai Nov 21 '22 at 19:05

1 Answers1

3

If each of your customer is having a separate instance installed (If I understand correctly! Basically I recommend to handle these things in CI/CD pipelines.) ,you can do this: First create and derive a class from RazorViewEngine:

public class MultiImplementationRazorViewEngine : RazorViewEngine
    {

        private static string _currentImplementation = /*Link to a config file to have your */;

        public MultiImplementationRazorViewEngine()
            : this(_currentImplementation)
        {
        }

        public MultiImplementationRazorViewEngine(string impl)
        {
            SetCurrentImplementation(impl);
        }

        public void SetCurrentImplementation(string impl)
        {
            if (string.IsNullOrWhiteSpace(impl))
            {
                this.ViewLocationFormats = new string[] {
                @"~/Views/{1}/{0}.cshtml",
                @"~/Views/Shared/{0}.cshtml"};
            }
            else
            {
                _currentImplementation = impl;
                ICollection<string> arViewLocationFormats =
                     new string[] { "~/Views/Overrides/" + impl + "/{1}/{0}.cshtml" };
                ICollection<string> arBaseViewLocationFormats = new string[] {
                @"~/Views/{1}/{0}.cshtml",
                @"~/Views/Shared/{0}.cshtml"};
                this.ViewLocationFormats = arViewLocationFormats.Concat(arBaseViewLocationFormats).ToArray();
            }
        }

        public static string CurrentImplementation
        {
            get { return _currentImplementation; }
        }

    }

Then in startup.cs add these lines to replace the razor engine:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MultiImplementationRazorViewEngine());
MD Zand
  • 2,366
  • 3
  • 14
  • 25