简体   繁体   中英

Load favicon dynamically into shared _Layout.cshtml

How to add favicon dynamically(programatically based on conditions) into the Razor of shared _Layout.cshtml ? The master layout.

Without more details it's basically:

<head>
@if (true)
{
    <link rel="shortcut icon" href="http://example.com/favicon.ico" />
}
else
{
    <link rel="shortcut icon" href="http://example.com/favicon2.ico" />
}
</head>

You could do a child action in the _Layout

@Html.Action("Favicon", "MyController", new { parameter = "value" })

With an action

[ChildActionOnly]
public ActionResult Favicon(string parameter)
{
    string url = GetFaviconUrl(parameter);
    ViewBag.FaviconUrl = url;
    return PartialView();
}

And the partial

<link rel="shortcut icon" href="@ViewBag.FaviconUrl" />

I know this question is old, but I just had to do this and didn't find a good way online that would fit what I needed so I am posting this answer to give others another way that might help.

I have a health status page and wanted to be able to see a red, yellow or green icon as the favicon so as I'm on SO researching another issue, I can quickly check the status of the company apps. Each section on the status page is a ViewComponent and all of them are called from Index.cshtml

Through trying various things, I found out that the _Layout.cshtml gets called AFTER all the View Components get rendered which greatly simplified this process. All the View Components set their specific status, for example the ApiStatusViewComponent sets the Shared.ApiStatus variable. On each call, the overallStatus gets updated (wasted processor cycles I know but it works). By the time Index.cshtml calls _Layout.cshtml, the overallStatus is already reflecting the correct value.

Code examples below:

_Layout.cshtml

<link rel="icon" type="image/png" sizes="923x923" href=@Shared.GetFavIcon() />

It's a big icon I know, but the browsers get it shrunk down to the size needed for the platform.

Shared.cs

public static class Shared
    {
        private static OverallStatusEnum overallStatus;

        public static string GetFavIcon()
        {
            switch (overallStatus)
            {
                case OverallStatusEnum.Ok:
                    return "https://PathToServer/Green.png";
                case OverallStatusEnum.Warning:
                    return "https://PathToServer/Yellow.png";
                case OverallStatusEnum.Error:
                    return "https://PathToServer/Red.png";
                default:
                    return "https://PathToServer/Yellow.png";
            }
        }

        public static class Status
        {
            private static OverallStatusEnum apiStatus;
            private static OverallStatusEnum criticalServicesStatus;

            // When adding a new section to monitor, add the overall status here so the favicon can be updated
            public static OverallStatusEnum ApiStatus { get => apiStatus; set => UpdateStatus(value, nameof(ApiStatus)); }
            public static OverallStatusEnum CriticalServicesStatus { get => criticalServicesStatus; set => UpdateStatus(value, nameof(CriticalServicesStatus)); }

            private static void UpdateStatus(OverallStatusEnum status, string propertyName)
            {
                switch(propertyName)
                {
                    case nameof(ApiStatus):
                        apiStatus = status;
                        break;
                    case nameof(CriticalServicesStatus):
                        criticalServicesStatus = status;
                        break;
                }

                overallStatus = (OverallStatusEnum)GetHighestStatusLevel();
            }

            private static int GetHighestStatusLevel()
            {
                var highestLevel = -1;
                var type = typeof(Status);
                foreach (var p in type.GetFields(BindingFlags.Static | BindingFlags.NonPublic))
                {
                    var v = p.GetValue(null); // static classes cannot be instanced, so use null...
                    if (highestLevel > (int)v || highestLevel == (int)v)
                        continue;
                    highestLevel = (int)v;
                }
                return highestLevel;
            }
        }
    }

OverallStatusEnum

public enum OverallStatusEnum
        {
            Ok,
            Warning,
            Error
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM