I'm trying to better understand the "behind the scenes" on view components. I know that the standard approach is to invoke the ViewComponent
by using
@await Component.InvokeAsync("MyViewComponent", itsModel)
or a view component tag helper in the .cshtml file.
It's possible however to use view componets other ways. So for example you can return a view directly from a controller by using return ViewComponent("MyViewComponent", itsModel);
from an action method.
It seems like it should be possible to easily render the view component to a string. I see that on the ViewComponetResult
returned by ViewComponent("MyViewComponent", itsModel);
there is an ExecuteResult
method.
In a controller it can be called like this:
ViewComponent("MyViewComponent", itsModel).ExecuteResult(this.ControllerContext);
At first blush I'd expect such a method to return a string of html. But it returns void. Why? What is ViewComponentResult.ExecuteResult
doing if it's not returning a result? And how can I render a ViewComponentResult
into a string of HTML?
I finally understand how this works. @TavisJ's comment is what tipped me of and sent me researching in the right direction.
On a ViewComponentResult
or more universally, on any ActionResult
the ExecuteResult
returns void because the output of the ViewComponent
is written to the associated HttpResponse.Body
. This is true of the async version of the call as well except that of course it returns a Task.
So for example, if a person were to make the following call:
await ViewComponent("MyViewComponent", itsModel).ExecuteResultAsync(this.ControllerContext);
to capture the "output" of the view component, one would first need to replace the this.ControllerContext.HttpResponse.Response.Body
with a stream of their choice before making the ExecuteResultAsync
call so that the output is captured in a stream that can then be converted to a string.
Then of course, the original stream should be put back on the this.ControllerContext.HttpResponse.Response.Body
so the rest of the view renders correctly.