I'm trying to sanitize content of MarkupString. Actually I created this (based from https://github.com/dotnet/aspnetcore/blob/574be0d22c1678ed5f6db990aec78b4db587b267/src/Components/Components/src/MarkupString.cs)
public struct MarkupStringSanitized
{
public MarkupStringSanitized(string value)
{
Value = value.Sanitize();
}
public string Value { get; }
public static explicit operator MarkupStringSanitized(string value) => new MarkupStringSanitized(value);
public override string ToString() => Value ?? string.Empty;
}
But render output isn't raw html. How should I implement MarkupStringSanitized to use
@((MarkupStringSanitized)"Sanitize this content")
Couple of suggestions (Not necessarily for OP, but for anyone else looking to solve the problem):
Sanitize()
method should follow the pattern of immutability
in this caseGans.XSS.HtmlSanitizer
which is an active library and updated regularly.Razor View Engine can doesn't know how to render a MarkupStringSanitized
. Just because you duck typed a sanitized version of the same struct
doesn't mean it can render it. To get this to render, you'll need to cast it to something it does know, MarkupString
Here's what happens when I used your HtmlSanitizedMarkup
directly with no modifications.
@((MarkupStringSanitized)Content)
Here's an example using my Markdown -> Html playground (fully tested and working):
MarkupStringSanitized.cspublic struct MarkupStringSanitized
{
public MarkupStringSanitized(string value)
{
Value = Sanitize(value);
}
public string Value { get; }
public static explicit operator MarkupStringSanitized(string value) => new MarkupStringSanitized(value);
public static explicit operator MarkupString(MarkupStringSanitized value) => new MarkupString(value.Value);
public override string ToString() => Value ?? string.Empty;
private static string Sanitize(string value) {
var sanitizer = new HtmlSanitizer();
return sanitizer.Sanitize(value);
}
}
MarkupStringSanitizedComponent.razor
@if (Content == null)
{
<span>Loading...</span>
}
else
{
@((MarkupString)(MarkupStringSanitized)Content)
}
@code {
[Parameter] public string Content { get; set; }
}
That extra conversion though is ugly IMO. (maybe someone smarter than me can clean that up?)
Here I tried extending the MarkupString
with an extension method. It looks a little better, but only a little.
public static class MarkupStringExtensions
{
public static MarkupString Sanitize(this MarkupString markupString)
{
return new MarkupString(SanitizeInput(markupString.Value));
}
private static string SanitizeInput(string value)
{
var sanitizer = new HtmlSanitizer();
return sanitizer.Sanitize(value);
}
}
MarkupStringSanitizedComponent.razor
@if (Content == null)
{
<span>Loading...</span>
}
else
{
@(((MarkupString)Content).Sanitize())
}
@code {
[Parameter] public string Content { get; set; }
}