Search code examples
c#asp.net-coredependency-injectionhtml-sanitizing

HtmlSanitizer + ASP.NET Core 2 with DI


When I use HtmlSanitizer without DI it works well.

HtmlSanitizer without DI:

HtmlSanitizer without DI

But when I want to get HtmlSanitizer using DI.

  1. I added to Startup.cs file:

    services.AddSingleton<IHtmlSanitizer, HtmlSanitizer>();
    
  2. I used constructor of repository to get instance of IHtmlSanitizer but in the injected HtmlSanitizer instance, AllowedTags, and AllowAttributes are empty.

HtmlSanitizer with DI:

HtmlSanitizer with DI

How can I get HtmlSanitizer with filled properties using DI?


Solution

  • The .Net framework dependency injection is trying to inject the optional constructor parameters

        public HtmlSanitizer(IEnumerable<string> allowedTags = null, IEnumerable<string> allowedSchemes = null,
            IEnumerable<string> allowedAttributes = null, IEnumerable<string> uriAttributes = null, IEnumerable<string> allowedCssProperties = null, IEnumerable<string> allowedCssClasses = null)
        {
            AllowedTags = new HashSet<string>(allowedTags ?? DefaultAllowedTags, StringComparer.OrdinalIgnoreCase);
            AllowedSchemes = new HashSet<string>(allowedSchemes ?? DefaultAllowedSchemes, StringComparer.OrdinalIgnoreCase);
            AllowedAttributes = new HashSet<string>(allowedAttributes ?? DefaultAllowedAttributes, StringComparer.OrdinalIgnoreCase);
            UriAttributes = new HashSet<string>(uriAttributes ?? DefaultUriAttributes, StringComparer.OrdinalIgnoreCase);
            AllowedCssProperties = new HashSet<string>(allowedCssProperties ?? DefaultAllowedCssProperties, StringComparer.OrdinalIgnoreCase);
            AllowedAtRules = new HashSet<CssRuleType>(DefaultAllowedAtRules);
            AllowedCssClasses = allowedCssClasses != null ? new HashSet<string>(allowedCssClasses) : null;
        }
    

    Source

    which results in empty collections being used by the DI container to initialize the target HtmlSanitizer class.

    In this case, use the factory delegate when registering the class and call the constructor (just as was done when not using DI)

    services.AddSingleton<IHtmlSanitizer>(_ => new HtmlSanitizer());
    

    Or simply create the instance and register it with the DI container

    IHtmlSanitizer sanitizer = new HtmlSanitizer();
    services.AddSingleton<IHtmlSanitizer>(sanitizer);