4

I would like to pass csHtml to a ViewComponent like this:

<vc:some-component title="Title" 
body="@Html.Raw("<div>this is a nice div, my name is @Model.Name</div>")">
</vc:some-component>

As you can see, I want to pass HTML that contains references to variables or the model (that's why I'm calling it csHtml and not just Html).

And here is the ViewComponent code:

<div>
    <p>@Model.Title</p>
    @Model.Content
</div>

Is this even possible? I've been searching and haven't found any examples of how to do this.


Edit: Got it working! Thanks everyone for your help.

Here is some sample code for how to do this:

Calling ViewComponent:

@{
    Func<dynamic, object> children =
    @<div>
        <p style="color: white">aaaa</p>
        <p style="color: white">bbbb</p>
        <p style="color: white">bbbb</p>
    </div>;
}

<vc:some-component body=@children>
</vc:some-component>

View Component content:

@model SomeComponentModel

<div>
    @Model.Body("")
</div>
Ryan
  • 524
  • 5
  • 16

2 Answers2

3

You should be able to add the parameters to the ViewComponent and pass them along towards the ViewComponent view itself as you go.

<vc:some-component title="Title" 
body="@Html.Raw("<div>this is a nice div, my name is @Model.Name</div>")">
</vc:some-component>

or something similar to this

 @await Component.InvokeAsync("SomeComponent", new { title="Title", body= Html.Raw($"<div>this is a nice div, my name is {Model.Name}</div>") })

Your viewcomponent IViewComponentResult would look something like this, using ViewBag just as example

public async Task<IViewComponentResult> InvokeAsync(string title, string body)
{
    //...
    ViewBag.Content = body;
    ViewBag.Title = title;
    //...
    return View();
}

And then in the related ViewComponent View

<div>
    <p>@ViewBag.Title</p>
    @ViewBag.Content
</div>

Creating a more specific ViewModel to pass along would also be an option ofcourse

Zephire
  • 394
  • 7
  • 16
1

Yes it is possible, you have to make a workaround but it is achievable,this answer has an example of what you are looking for.

Albondi
  • 1,141
  • 1
  • 8
  • 19
  • 1
    So it's actually a duplicate question? –  Aug 27 '19 at 19:51
  • Not exactly but very similar. – Albondi Aug 27 '19 at 19:53
  • I tried that solution but it's not working for me. When I try to pass the csHtml I get this compile time error: "Cannot implicitly convert type 'System.Func' to 'Microsoft.AspNetCore.Html.HtmlString'". – Ryan Aug 27 '19 at 22:07
  • Here's the code: @{Func children = @

    aaaa

    bbbb

    ccccc

    }
    – Ryan Aug 27 '19 at 22:08
  • My bad, I missed adding the semicolon. Now it's rendering but on the page it looks like like this "System.Func`2[System.Object,System.Object]", it doesn't render the actual HTML properly. – Ryan Aug 27 '19 at 22:27
  • Had to call invoke! Now it's all good, will update my question with the solution – Ryan Aug 27 '19 at 22:36