SLaks.Blog

Making the world a better place, one line of code at a time

Writing output in Razor helpers using code

Posted on Wednesday, January 12, 2011, at 8:22:00 PM UTC

The new ASP.Net WebPages view engine (formerly Razor) allows you to create reusable parameterized blocks of HTML called helpers

For example:

@helper Fibonacci(int count) {
int current = 1, prev = 0;
for (int i = 0; i < count; i++) {
@:@current,
int t = current;
current += prev;
prev = t;
}
}

This helper will write out the first count Fibonacci numbers.  It can be called by writing @Fibonacci(30) in the page that defines the helper.

Using Razor syntax in this code looks strange.  Razor syntax is designed to write HTML tags.  Since I’m printing plain text, I need to use the  @: escape (or the <text> tag) in order to output my text.  This small bit of code looks confusing and can get lost inside larger blocks of server-side code.

Instead, I can use an undocumented hack.  Razor helpers are implemented by compiling a lambda expression as an Action<TextWriter>.  The lambda expression receives a TextWriter parameter named __razor_helper_writer.  (You can see this by writing a Razor page with a compilation error and clicking Show Complete Compilation Source)  There is nothing preventing me from using this parameter yourself.  (it even shows up in IntelliSense!)

Therefore, I can rewrite the helper as follows:

@helper Fibonacci(int count) {
int current = 1, prev = 0;
for (int i = 0; i &lt; count; i++) {
__razor_helper_writer.Write(current + &quot;, &quot;);
int t = current;
current += prev;
prev = t;
}
}

Remember to correctly escape your text by calling Html.Encode.  Since this writes directly to the output stream, it doesn’t get the benefit of Razor’s automatic escaping.

Note: This relies on undocumented implementation details of the Razor compiler, and may change in future releases. I would not recommend doing this.
Instead, you can write a function:

@functions {
string Fibonacci(int count) {
var builder = new System.Text.StringBuilder();
int current = 1, prev = 0;
for (int i = 0; i &lt; count; i++) {
builder.Append(current).Append(&quot;, &quot;);

int t = current;
current += prev;
prev = t;
}
return builder.ToString();
}
}
This can be called the same way as the helper.  Instead of using the special helper support, the call will just print a string, the same you print any other string.  Therefore, the function’s output will be HTML-escaped.  To prevent that, you can change the function to return an HtmlString.

Categories: Razor, ASP.Net WebPages, Razor-helpers, C#, ASP.Net, .Net Tweet this post

comments powered by Disqus