4

For very simple ViewComponents I'd like to bypass a view and just return an encoded HTML string.

Example:

<ul>
   <li>One</li>
   <li>Two</li>
<ul>

My self-made implementation is like this:

public class RawHtmlResult : IViewComponentResult
{
    public RawHtmlResult(string EncodedHtml)
    {
        _encodedHtml = EncodedHtml;
    }
    public string _encodedHtml { get; set; }

    public void Execute(ViewComponentContext context)
    {
        context.Writer.Write(_encodedHtml);
    }

    public Task ExecuteAsync(ViewComponentContext context)
    {
        return context.Writer.WriteAsync(_encodedHtml);
    }
}

Usage:

public async Task<IViewComponentResult> InvokeAsync(long id)
{
    var someArray = await _someService(id);
    var ulHelper = new TagBuilder("ul");
    var liHelper = new TagBuilder("li");

    foreach (var setName in someArray)
    {
        liHelper = new TagBuilder("li");
        liHelper.InnerHtml.Append(setName);
        ulHelper.InnerHtml.Append(liHelper);
    }
    var writer = new System.IO.StringWriter();
    ulHelper.WriteTo(writer, new HtmlEncoder());

    return new RawHtmlResult(writer.ToString());
}

So far I have not found a suitable IViewComponentResult. Do I miss apoint?

5
  • A View is raw html, mixed with markup. A controller should not have to do anything with rendering. Otherwise you shouldn't use MVC at all - it's the wrong pattern. Perhaps you are trying to solve a different problem? Why would you want to create raw HTML like this inside an MVC framework? Commented Apr 13, 2016 at 12:11
  • 1
    Maybe he is developing a CMS and his articlebody is stored as HTML in the database? ;) Commented Apr 13, 2016 at 13:28
  • You may also look into HtmlString. Used it a bit different answer for tag-helper content being encoded. stackoverflow.com/a/35672341/455493 Not sure though on how to use it inside a controller Commented Apr 13, 2016 at 13:36
  • 1
    @PanagiotisKanavos: You have been absolutely right about MVC usage and I agree. Still, sometimes you do not need to follow the path 100% and I can keep my codebase smaller not introducing another "partial view"... Returning Content("foo", "text/html"); does not work because ViewComponent only support returning String, HtmlString or IViewComponentResult. Thanks for you help! Commented Apr 14, 2016 at 14:35
  • @kdaveid Not in this case. You can easily return an array of values and use a loop in the View. Or use a proper model and pass the array as one of its properties. The total number of lines is less than what you already typed Commented Apr 14, 2016 at 15:48

3 Answers 3

4

The Invoke() method on the view component does not need to return IViewComponentResult, it can return HtmlString so you don't need a custom implementation of IViewComponentResult.

For example:

public HtmlString Invoke()
{
    return new HtmlString(@"<b>Hello World</b>");
}
Sign up to request clarification or add additional context in comments.

Comments

1
return Content("<ul><li>One</li><li>Two</li><ul>");

The method is Controller.Content. You can also use it to return content types other than HTML.

As mentioned it's not the preferred way to return HTML - typically the controller should return a model and the view should provide HTML. It might be preferable to use a partial view. But scenarios come up where we have to do things like this. (I just encountered one myself.)

6 Comments

You also need to specify the 2nd argument, content type: Content(html,"text/html")
The second argument is optional.
I was under the impression that if you omitted the content-type it would always return text/plain but I just checked and it returns the correct content-type. Maybe that's new since MVC3.
The question is about ASP.NET Core / MVC6. The provided link refers to old framework up to MVC5, so likely not valid as MVC6 is a complete rewrite w/o System.Web.* and IIS dependencies
This does not work: Returning Content("foo", "text/html"); does not work because ViewComponent only support returning String, HtmlString or IViewComponentResult. (see above)
|
1

For future visitors:

The easiest way to return HtmlContentViewComponentResult from Invoke() method. HtmlContentViewComponentResult is one of 3 classes which implements IViewComponentResult interface.

Here is the example code:

public IViewComponentResult Invoke(object arguments)
{
    return new HtmlContentViewComponentResult(
        new HtmlString("<ul><li>My HTML code</li></ul>"));
}

As you may see HtmlContentViewComponentResult requires IHtmlContent as content to render on view, so best way is to use HtmlString class.


Still for more complex results it's better to return View instead of generating raw HTML programmatically.

Comments

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.