1

Lets say I have a ViewComponent named MyComponent.

As of ASP.NET Core 1.1 I can render this ViewComponent by writing this inside a razor view .cshtml page:

 <vc:my-component></vc:my-component>

I want to do something like this:

@{string myHtml = "<vc:my-component></vc:my-component>";}

@(new HtmlString(myHtml))

I installed and tried RazorEngine by doing this, but this did not work:

string template = "<vc:my-component></vc:my-component>";
var result = Engine.Razor.RunCompile(template, "messageTemplateKey", null, new { Name = "some model data" });
ViewBag.result = result;

then in the .chtml file:

 @(new HtmlString(ViewBag.result))

The backstory to this is that I've created a ViewComponent with some logic on how to handle image files, now I want to search and replace all img tags in some html with my ViewComponent. Before I do that I need to make sure this even works.

1
  • Since there are examples of rendering a view to a string on stack overflow, wouldn't it work to create a view and put code in it to use your view component and then just render the view to a string? I'm pretty sure that should work for you. Commented Apr 9, 2017 at 4:13

2 Answers 2

2

Check the code at this url on github:

https://gist.github.com/pauldotknopf/b424e9b8b03d31d67f3cce59f09ab17f


Code

public class HomeController : Controller {

  public async Task<string> RenderViewComponent(string viewComponent, object args) {

    var sp = HttpContext.RequestServices;

    var helper = new DefaultViewComponentHelper(
        sp.GetRequiredService<IViewComponentDescriptorCollectionProvider>(),
        HtmlEncoder.Default,
        sp.GetRequiredService<IViewComponentSelector>(),
        sp.GetRequiredService<IViewComponentInvokerFactory>(),
        sp.GetRequiredService<IViewBufferScope>());

    using (var writer = new StringWriter()) {
        var context = new ViewContext(ControllerContext, NullView.Instance, ViewData, TempData, writer, new HtmlHelperOptions());
        helper.Contextualize(context);
        var result = await helper.InvokeAsync(viewComponent, args);
        result.WriteTo(writer, HtmlEncoder.Default);
        await writer.FlushAsync();
        return writer.ToString();
    }
  }}

Sign up to request clarification or add additional context in comments.

1 Comment

Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
1

This is what I ended up doing:

I moved the view code from the Default.cshtml for MyComponent to a partial view (_myPartial). Then I used a IViewRenderService inspired by this post.

Then I could render and get my html string after passing in the viewmodel by doing this:

 var result = ViewRenderService.RenderToString("_myPartial", viewModel);

1 Comment

@TobiOwolawi this example is a view component. I just had to move the html/razor code from the view components Default.cshtml to a partial view. In that way I could both use the view component and retrieve the rendered html by using the partial view underneath

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.