0 Comments

In some child & parent component situations it would be good if you could render or at least get an access to an instance of a Blazor Component.

Given the following scenario where we try to render an instance of the Counter-component inside the Index-component:

<h1>Hello, world!</h1>

Welcome to your new app.

@counterInstance

@functions{
    Counter counterInstance = new Counter();
}

The following doesn’t work as it only draws the type name of the component:

image

There are couple options around this.

Capturing reference

In many (if not most?) cases you should let Razor Components to take care of creating the instance of your component and then use the “ref” keyword to capture the rendered instance:

<h1>Hello, world!</h1>

Welcome to your new app.

@DrawCounter()

@functions{

    private Counter _myCounter = null;

    RenderFragment DrawCounter()
    {
        return new RenderFragment(builder =>
        {
            builder.OpenComponent<Counter>(0);
            builder.AddComponentReferenceCapture(1, inst => { _myCounter = (Counter)inst; });
            builder.CloseComponent();
        });
    }

Reflection

If you really want, you can access the RenderFragment of the instance using reflection and then draw that:

Welcome to your new app.

@RenderContent(counterInstance)

@functions{
    Counter counterInstance = new Counter();

    RenderFragment RenderContent(ComponentBase instance)
    {
        var fragmentField = GetPrivateField(instance.GetType(), "_renderFragment");

        var value = (RenderFragment)fragmentField.GetValue(instance);

        return value;
    }

    //https://stackoverflow.com/a/48551735/66988
    private static FieldInfo GetPrivateField(Type t, String name)
    {
        const BindingFlags bf = BindingFlags.Instance |
                                BindingFlags.NonPublic |
                                BindingFlags.DeclaredOnly;

        FieldInfo fi;
        while ((fi = t.GetField(name, bf)) == null && (t = t.BaseType) != null) ;

        return fi;
    }

0 Comments

ASP.NET Core ViewComponents usually come in pairs: There’s the class which inherits ViewComponent and there’s the Razor view which is returned by the class:

image

In most of the situations the ViewComponent runs some logic and then returns the view:

    public class MyTest : ViewComponent
    {
        public Task<IViewComponentResult> InvokeAsync(string content)
        {
            return Task.FromResult<IViewComponentResult>(View("Default"));
        }
    }

But what if you need to return the view only in some cases based on the ViewComponent’s parameters or because of some other validation? In these situation you can skip returning the view by returning empty content instead:

    public class MyTest : ViewComponent
    {
        public Task<IViewComponentResult> InvokeAsync(string content)
        {

            if (string.IsNullOrWhiteSpace(content))
            {
                return Task.FromResult<IViewComponentResult>(Content(string.Empty));
            }

            return Task.FromResult<IViewComponentResult>(View("Default", content));
        }
    }