Make Microsoft.AspNetCore.Html.HtmlString implement System.Web.IHtmlString
See original GitHub issueBackground and Motivation
Given that System.Web.IHtmlString
is being added to the runtime in .NET 8 without the corresponding System.Web.HtmlString implementation, we decided in runtime API review that it makes sense to have ASP.NET Core’s HtmlString
implement the interface. See https://github.com/dotnet/runtime/issues/83477.
Proposed API
// Microsoft.AspNetCore.Html.Abstractions.dll
namespace Microsoft.AspNetCore.Html;
- public class HtmlString : IHtmlContent
+ public class HtmlString : IHtmlContent, System.Web.IHtmlString
{
+ string IHtmlString.ToHtmlString();
}
Usage Examples
You can use code blocks like this:
var myHtml = new HtmlString("<strong>My important safe HTML content!</strong>");
LegacyApiThatStillCallsHttpUtilityHtmlEncode(myHtml);
Alternative Designs
We could add a default interface implementation to IHtmlContent
as suggested by @twsouthwick in the runtime issue. This might make it less clear to consumers of the interface that the WriteTo
implementation is generally preferred.
- public interface IHtmlContent
+ public interface IHtmlContent : System.Web.IHtmlString
{
void WriteTo(TextWriter writer, HtmlEncoder encoder);
+ string System.Web.IHtmlString.ToHtmlString()
+ {
+ using var writer = new StringWriter();
+ WriteTo(writer, HtmlEncoder.Default);
+ return writer.ToString();
+ }
}
We could consider making ToHtmlString()
fully public. I decide against that in the primary proposal since HtmlString.Value
provides an existing way to get the original string from an ASP.NET Core HtmlString
.
- public class HtmlString : IHtmlContent
+ public class HtmlString : IHtmlContent, System.Web.IHtmlString
{
+ public string ToHtmlString();
}
We could also consider implementing IHtmlString
on a few more specific types like HtmlFormattableString
and LocalizedHtmlString
. This could be either as an alternative or in addition to the default interface implementation. The original runtime proposal just suggested bringing over HtmlString
though, so I think it’s safest to start with that.
Or we could decide to not implement IHtmlString
at all and say implement it yourself since it’s so easy to do.
Risks
- We unintentionally encourage more usage of
IHtmlString
instead ofIHtmlContent
orIHtmlAsyncContent
which would generally be preferred in ASP.NET Core. - People think that since one built-in
IHtmlContent
implementation implementsIHtmlString
, they all do.
Issue Analytics
- State:
- Created 5 months ago
- Reactions:1
- Comments:7 (7 by maintainers)
IHtmlContent
more than call it. Can the components that useIHtmlContent
like the razor compiler instead just supportIHtmlString
directly?WriteTo
and the otherIHtmlString
methods for legacy, so it’d be better to hide it.HttpUtility.HtmlEncode
with anIHtmlContent
?For now, we’re going to reject this API unless we hear back that there’s a strong need.
One of the main goals of the System.Web adapters project is to allow people to compile their libraries to .NET Standard without having to rewrite the world. In that direction, I’d like to implement the
System.Web.HtmlString
type in the adapters and have it follow the current pattern of type forward on .NET Framework, while providing a .NET Standard way of referencing it.Since we want to push people to use the ASP.NET Core type, we can use the adapters to bridge the two worlds, including automatic conversion between the System.Web and the ASP.NET Core representation (this kind of conversion is a common pattern we’ve set up in the adapters to help people slowly migrate code):
See https://github.com/dotnet/systemweb-adapters/compare/main...tasou/htmlstring
@CZEMacLeod I know you’ve been interested in this feature - do you have an opinion here?