ASP.NET Core MVC中存储硬编码域名的最佳方案咨询
Great question—hardcoding domain names isn’t just a security tool red flag (like Fortify is flagging), it also makes your app a pain to maintain if those CDN domains ever change. Let’s walk through the best app-side (no database needed) approaches to handle this cleanly in ASP.NET Core MVC:
This is the most straightforward approach since ASP.NET Core is built around configuration.
First, add a section to your appsettings.json to store all your external domain bases:
{ "ExternalResources": { "FontAwesomeCdn": "https://stackpath.bootstrapcdn.com/font-awesome/4.7.0", "KendoCdn": "https://kendo.cdn.telerik.com/2018.1.221", "AspNetBootstrapCdn": "https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7" } }
You can even override these for specific environments (like development) using appsettings.Development.json—for example, pointing to local resources instead of CDNs when testing.
Then, in your Razor views, inject the IConfiguration service and build your URLs dynamically:
@inject IConfiguration Configuration <link rel="stylesheet" href="@($"{Configuration["ExternalResources:FontAwesomeCdn"]}/css/font-awesome.min.css")"> <link rel="stylesheet" href="@($"{Configuration["ExternalResources:KendoCdn"]}/styles/kendo.common.min.css")">
For your environment-specific example, it would look like this:
<environment exclude="Development"> <link rel="stylesheet" href="@($"{Configuration["ExternalResources:AspNetBootstrapCdn"]}/css/bootstrap.min.css")" asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" /> </environment>
If you don’t want to inject IConfiguration into every view, create a static class to hold your URLs and initialize it at app startup.
First, define the class:
public static class ExternalResourceUrls { public static string FontAwesomeCdn { get; set; } public static string KendoCdn { get; set; } public static string AspNetBootstrapCdn { get; set; } }
Then, in Program.cs (or Startup.cs if you’re using an older template), populate it from configuration:
var builder = WebApplication.CreateBuilder(args); // Load values from appsettings ExternalResourceUrls.FontAwesomeCdn = builder.Configuration["ExternalResources:FontAwesomeCdn"]; ExternalResourceUrls.KendoCdn = builder.Configuration["ExternalResources:KendoCdn"]; ExternalResourceUrls.AspNetBootstrapCdn = builder.Configuration["ExternalResources:AspNetBootstrapCdn"]; // Rest of your setup...
Now you can use it directly in views without injection:
<link rel="stylesheet" href="@($"{ExternalResourceUrls.FontAwesomeCdn}/css/font-awesome.min.css")">
For even cleaner view code, create a custom Tag Helper that handles the CDN URL resolution for you.
First, create the Tag Helper class:
using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.Configuration; [HtmlTargetElement("link", Attributes = "cdn-resource")] public class CdnLinkTagHelper : TagHelper { private readonly IConfiguration _config; public CdnLinkTagHelper(IConfiguration config) { _config = config; } // Expected format: "CdnName|resource-path" (e.g., "FontAwesomeCdn|/css/font-awesome.min.css") [HtmlAttributeName("cdn-resource")] public string CdnResource { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { var parts = CdnResource.Split('|'); if (parts.Length != 2) return; var cdnBase = _config[$"ExternalResources:{parts[0]}"]; var fullUrl = $"{cdnBase}{parts[1]}"; output.Attributes.SetAttribute("href", fullUrl); } }
Register the Tag Helper in your _ViewImports.cshtml so it’s available across all views:
@addTagHelper *, YourAppAssemblyName
Now you can use it in views like this:
<link rel="stylesheet" cdn-resource="FontAwesomeCdn|/css/font-awesome.min.css"> <link rel="stylesheet" cdn-resource="KendoCdn|/styles/kendo.common.min.css">
This keeps your views tidy and centralizes all CDN configuration in one place.
Bonus Tips
- Validate Configuration: Add checks in
Program.csto ensure all required CDN URLs are present at startup—throw an exception if any are missing to catch issues early. - Versioning: If your CDN resources use version numbers (like the Kendo example), include the version in the configuration value. That way, updating versions only requires changing
appsettings.json, not every view. - Fallback Logic: Keep using the built-in
asp-fallback-*attributes as you were—they work perfectly with dynamically generated CDN URLs.
内容的提问来源于stack exchange,提问作者Kurkula

