Skip to content

Blazor: Preview9 made HtmlRenderer & ComponentRenderedText internal #13687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
chanan opened this issue Sep 4, 2019 · 14 comments
Open

Blazor: Preview9 made HtmlRenderer & ComponentRenderedText internal #13687

chanan opened this issue Sep 4, 2019 · 14 comments
Labels
affected-few This issue impacts only small number of customers area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-prerendering Issues related to prerendering blazor components reevaluate We need to reevaluate the issue and make a decision about it severity-minor This label is used by an internal tool
Milestone

Comments

@chanan
Copy link

chanan commented Sep 4, 2019

Two Libraries (that I know of) use HtmlRenderer & ComponentRenderedText prior to previw 9. One is BlazorStyled: https://github.com/chanan/BlazorStyled and the other is Egil's testing library: https://github.com/egil/razor-components-testing-library

Both use it for the same reason, to get the content of ChildContent. It was used like so:

private string RenderAsString()
{
    string result = string.Empty;
    try
    {
        ParameterView paramView = ParameterView.FromDictionary(new Dictionary<string, object>() { { "ChildContent", ChildContent } });
        using HtmlRenderer htmlRenderer = new HtmlRenderer(_emptyServiceProvider, NullLoggerFactory.Instance, _encoder);
        IEnumerable<string> tokens = GetResult(htmlRenderer.Dispatcher.InvokeAsync(() => htmlRenderer.RenderComponentAsync<TempComponent>(paramView)));
        result = string.Join("", tokens.ToArray());
    }
    catch
    {
        //ignored dont crash if can't get result
    }
    return result;
}

private IEnumerable<string> GetResult(Task<ComponentRenderedText> task)
{
    if (task.IsCompleted && task.Status == TaskStatus.RanToCompletion && !task.IsFaulted && !task.IsCanceled)
    {
        return task.Result.Tokens;
    }
    else
    {
        ExceptionDispatchInfo.Capture(task.Exception).Throw();
        throw new InvalidOperationException("We will never hit this line");
    }
}

However as of Preview9 that is no longer possible as HtmlRenderer & ComponentRenderedText are both internal - Please make them public (Or provide another way to get the content of ChildContent).

CC: @danroth27 @SteveSandersonMS @egil

@danroth27
Copy link
Member

@javiercn

@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Sep 4, 2019
@egil
Copy link
Contributor

egil commented Sep 4, 2019

I would like to add, that having an easy to use API, that can use/by default uses the same service provider as the renderer it is inside to turn a renderfragment into a string, will likely be a great addition to the Blazor library. I'm pretty sure there are going to be other devs out there who will need this feature but won't have the @SteveSandersonMS chops to create a custom renderer for their purpose either :-)

@akorchev
Copy link

akorchev commented Sep 5, 2019

Yep, this one is quite a bummer and rendered (pun intended) Radzen's Blazor design time not working.

@javiercn
Copy link
Member

javiercn commented Sep 5, 2019

In the past the APIs for accessing the data for producing the HTML were internal (private protected if I recall) but now they are public, so you can do the same thing HTML Renderer does yourself.

https://github.com/aspnet/AspNetCore/blob/master/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/HtmlRenderer.cs

Let me know if you run into any roadblocks.

Personally I would like to also bring this back on a future release, but I would like to make some API changes to improve performance.

@akorchev
Copy link

akorchev commented Sep 5, 2019

@javiercn it uses an internal struct https://github.com/aspnet/AspNetCore/blob/master/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/ComponentRenderedText.cs

Also there is this warning:

warning BL0006: The types in 'Microsoft.AspNetCore.Components.RenderTree' are not recommended for use outside of the Blazor framework. These  type definitions will change in future releases.

Other than that it seems to work.

@egil
Copy link
Contributor

egil commented Sep 5, 2019

In the past the APIs for accessing the data for producing the HTML were internal (private protected if I recall) but now they are public, so you can do the same thing HTML Renderer does yourself.

https://github.com/aspnet/AspNetCore/blob/master/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/HtmlRenderer.cs

Let me know if you run into any roadblocks.

Personally I would like to also bring this back on a future release, but I would like to make some API changes to improve performance.

@javiercn its no problem copy-pasting your version of HtmlRenderer.cs and ComponentRenderedText.cs. But please let us know when you have updates to them. Would very much like to stay compatible/up-to-date. Perf improvements sounds good, and please take input on a possible API update :)

And there is this warning:

warning BL0006: The types in 'Microsoft.AspNetCore.Components.RenderTree' are not recommended for use outside of the Blazor framework. These  type definitions will change in future releases.

@akorchev just suppress the warning. Its fair its there, since we are digging our feet into the low level APIs in Blazor.

This works for me. Create a GlobalSuppressions.cs in your project and add the following to it:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "BL0006:The types in 'Microsoft.AspNetCore.Components.RenderTree' are not recommended for use outside of the Blazor framework. These type definitions will change in future releases.",
    Justification = "I will take the chance",
    Scope = "namespaceanddescendants",
    Target = "<YOUR.NAMESPACE.HERE")]

@akorchev
Copy link

akorchev commented Sep 5, 2019

@javiercn well instead of using low-level Blazor API we could have just used the higher level and now internal HtmlRenderer ;) I am pretty sure those low-level APIs will break often and we will find that out after the release (as it happened now).

@javiercn What is the reasoning of having public low-level warning-producing API instead of public HtmlRenderer?

@javiercn
Copy link
Member

javiercn commented Sep 5, 2019

@akorchev The API in its current form is not very good.

@danroth27 Given the interest on this API can we consider the appropriate improvements in HtmlRenderer to make it public in 3.1? I don't think we should release the API in its current form if we have time to make it performant before 3.1. It should take 2 days tops.

@SteveSandersonMS
Copy link
Member

People can easily copy the relevant bits of the HtmlRenderer sources into their own projects. It's what I did for this unit testing prototype and took hardly any time. I'm not sure there's a need to rush this into 3.1.

@egil
Copy link
Contributor

egil commented Sep 5, 2019

@javiercn / @SteveSandersonMS just for the record, I am fine with doing a little copy/paste for now. It would however be lovely with a better API (and more performance). It doesn't have to become public in the close future, as long as you keep it reasonably copy-pastable while iterating on it.

@javiercn
Copy link
Member

javiercn commented Sep 5, 2019

@SteveSandersonMS If there's demand for it and prevents people using the pubternal API I think it brings goodness.

@akorchev
Copy link

akorchev commented Sep 5, 2019

@javiercn @SteveSandersonMS are there any planned changes in the Microsoft.AspNetCore.Components.RenderTree namespace before the official 3.0 release?

@SteveSandersonMS
Copy link
Member

@akorchev No render tree API changes are expected between preview 9 and final 3.0.

@mkArtakMSFT mkArtakMSFT added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Sep 5, 2019
@mkArtakMSFT mkArtakMSFT added this to the 5.0.0-preview1 milestone Sep 5, 2019
@michalczerwinski
Copy link

What is status of this? Can we at this point (after 3.1) assume using GetFrames() is acceptable?

Not being able to access it is a big limitation for more advanced Blazor scenarios. Some clear recommendation would be appreciated.

@javiercn javiercn added affected-few This issue impacts only small number of customers severity-minor This label is used by an internal tool labels Oct 9, 2020 — with ASP.NET Core Issue Ranking
@javiercn javiercn added feature-prerendering Issues related to prerendering blazor components reevaluate We need to reevaluate the issue and make a decision about it labels Apr 19, 2021
@dotnet dotnet deleted a comment Nov 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affected-few This issue impacts only small number of customers area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-prerendering Issues related to prerendering blazor components reevaluate We need to reevaluate the issue and make a decision about it severity-minor This label is used by an internal tool
Projects
None yet
Development

No branches or pull requests

8 participants