question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Make Microsoft.AspNetCore.Html.HtmlString implement System.Web.IHtmlString

See original GitHub issue

Background 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 of IHtmlContent or IHtmlAsyncContent which would generally be preferred in ASP.NET Core.
  • People think that since one built-in IHtmlContent implementation implements IHtmlString, they all do.

@stephentoub @twsouthwick

Issue Analytics

  • State:closed
  • Created 5 months ago
  • Reactions:1
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
halter73commented, Jul 24, 2023
  • People implement the IHtmlContent more than call it. Can the components that use IHtmlContent like the razor compiler instead just support IHtmlString directly?
    • This would be nice because most people don’t need to implement WriteTo and the other IHtmlString methods for legacy, so it’d be better to hide it.
  • What if people try to use HttpUtility.HtmlEncode with an IHtmlContent?
    • We’re not confident this is a real scenario. @twsouthwick Is this something that we think people will really need or want to do?

For now, we’re going to reject this API unless we hear back that there’s a strong need.

1reaction
twsouthwickcommented, May 3, 2023

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):

namespace System.Web;

public class HtmlString : IHtmlString
#if NET6_0_OR_GREATER
+  , IHtmlContent
#endif
{
  public HtmlString(string value);

  public string ToHtmlString();

  public override string ToString();

#if NET6_0_OR_GREATER
+  public void WriteTo(TextWriter writer, HtmlEncoder encoder);

+  public static implicit operator HtmlString?(Microsoft.AspNetCore.Html.HtmlString? other};

+  public static implicit operator Microsoft.AspNetCore.Html.HtmlString?(HtmlString other};
#endif
}

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?

Read more comments on GitHub >

github_iconTop Results From Across the Web

HtmlString Class (Microsoft.AspNetCore.Html)
An IHtmlContent implementation that wraps an HTML encoded String. public ref class HtmlString : Microsoft::AspNetCore::Html::IHtmlContent. C# Copy.
Read more >
Using Microsoft.AspNetCore.Html.HtmlString
Its a .Net Core 2.0 application running on Visual Studio 2017 I want to display an HTML string returned on the View. I...
Read more >
Microsoft.AspNetCore.Html.Abstractions 2.2.0
ASP.NET Core HTML abstractions used for building HTML content. Commonly used types: Microsoft.AspNetCore.Html.HtmlString Microsoft.
Read more >
A Step-by-Step Guide to Migrating a Project from ASP.NET ...
Here is a practical guide on migrating a project from ASP.NET MVC framework to ASP.NET Core. Step-by-step instruction written by the team of ......
Read more >
why ihtmlencodedstring instead of htmlstring or ihtmlstring
In a vanilla v9 project I would output content from an RTE like so: @Html.Raw(Model.BodyText). In a vanilla v8 project I would do...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found