How the .NET encoders differ
- WebUtility.HtmlEncode (and
HttpUtility.HtmlEncode, which gives the same result) encodes< > & " 'as< > & " ', the characters U+00A0 to U+00FF as decimal references (é becomesé), and emoji and other characters above U+FFFF as decimal references too. Other characters, such as € or Chinese, stay as they are. - HtmlEncoder.Default (System.Text.Encodings.Web, what Razor uses for
@value) encodes everything outside printable ASCII, and also'and+, as hexadecimal references: é becomeséand €€. Configure it withWebEncoderOptionsto let more characters through. - HttpUtility.HtmlAttributeEncode encodes only
" & ' <: enough inside a quoted attribute, not for element content (it leaves>).
Decoding: WebUtility.HtmlDecode knows the 253 named references of HTML 4 (é, , €...), not HTML5's newer names, and decimal and hex references; each needs its closing semicolon.
FAQ
Which HTML encoder should I use in ASP.NET Core?
Let Razor encode output (it uses HtmlEncoder.Default). In code that builds HTML, inject HtmlEncoder and use it too; WebUtility.HtmlEncode is fine where you need the smaller output.
Why does Razor turn my accented letters into é?
HtmlEncoder.Default encodes everything outside Basic Latin. Allow more ranges with builder.Services.AddWebEncoders(o => o.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.All)).
Why are &bogus; and   (without the semicolon) not decoded?
WebUtility.HtmlDecode decodes only the HTML 4 named references, and only with their closing semicolon. Unknown names, and references without the semicolon, stay as they are.