1

I have a simple Blazor component that take some inputs (some lists of object and few strings) and formats them into simple HTML for display, (tables generated from the lists of objects, simple text, etc.).

This HTML is a report that is intended to be both displayed to users in the app and also emailed to various people (via SendGrid). For compatibility, we are keeping the email HTML as simple as possible.

The component works fine, however I am not sure how to translate a component's markup portion into a simple string of escaped HTML so that I can pass the string to SendGrid and fire off an email.

I am aware of MarkupStrings, but I have only used them in reverse--to write a string containing HTML tags that will be properly displayed in my app. I can't find any suggestions for doing the conversion the way that I need it done.

Is there any simple way to have a component write all of its markup into a string so that I can email it out?

Or, would I be better off writing a .cs file with a static method that takes in the parameters in question, renders it into a MarkupString, and then passes the string both to SendGrid for email and also to a Blazor component for in-app display?

aterbo
  • 432
  • 7
  • 24
  • https://stackoverflow.com/questions/46540358/render-a-razor-page-to-string or https://github.com/Tyrrrz/MiniRazor – TheGeneral Dec 05 '21 at 07:48
  • There seems to be a lot of duplicates around razor pages also several tools I have seen floating about, i am not sure of the ramifications with blazor, however have you tried any of these? – TheGeneral Dec 05 '21 at 07:49

2 Answers2

1

Is there any simple way to have a component write all of its markup into a string so that I can email it out?

No, your C# code has no simple way to do this - you could use JS Interop to get the rendered HTML from the dom, but nothing built in for it.

Or, would I be better off writing a .cs file with a static method that takes in the parameters in question, renders it into a MarkupString, and then passes the string both to SendGrid for email and also to a Blazor component for in-app display?

That is a possibility - I can't comment on the value of that to you, but it is a technique that could work if the component you are rendering is static,

Mister Magoo
  • 7,452
  • 1
  • 20
  • 35
1

The simplest way to do that is to employ JSInterop to retrieve the Html markup for the component, produced by the browser. Let's say You've defined a child component, and you want to retrieve its html source. You can do that like this:

Define the child...

SelectGender.razor

<div id="selectGender">
    <h1>Select Gender</h1>

    <select>
        @foreach (var gender in genders)
        {
            <option>@gender</option>

        }
    </select>
</div>

@code {

    private List<string> genders = new List<string> { "Male", "Female", "Other" };
    
}

Usage

@page "/"

@inject IJSRuntime JSRuntime

    <div>@((MarkupString) html)</div>
  
<SelectGender />

<button @onclick="GetHtml">Get Html</button>



@code{
    
    private string html;


    protected async Task GetHtml()
    {
        html = await JSRuntime.InvokeAsync<string>("myJsFunctions.getHtml");

    }

}

_Host.cshtml

<script>

        window.myJsFunctions =
        {
            getHtml: function () {
                return document.getElementById("selectGender").innerHTML;
            }
        };
    </script>
enet
  • 41,195
  • 5
  • 76
  • 113
  • Thanks, enet, this definitely does the trick. To prevent my component in question from being rendered to the screen (which isn't always necessary in my case), I wrapped it in two divs, like: `div style="visibility:hidden">
    `.
    – aterbo Dec 06 '21 at 06:09
  • Note: The purpose of this answer is to demonstrate how to get the Html produced by the component. That is what you were looking for, right ? Displaying it in a div, as I did, was done only to show you that it works. However, you don't have to do what you did... You'll need a parent component, and a child component whose Html representation you'll read in the parent component, and then pass it to the code that send your email... – enet Dec 06 '21 at 09:21