18

Apparently it is possible to write formatted output using the <%= %> construct (render block) in ASP.NET web forms pages and views.

<%= "{0} is {1}", "Foo", 42 %>

This will render "Foo is 42". As far as I know the ASP.NET parser translates <%= %> into a call to HttpResponse.Write(string). Obviously in the code above, there is no one-to-one translation, because the number of arguments don't match (assuming the , in the expression above separates arguments).

Now I have seen that the class TextWriter has a Write(string, object[]) method.

I have checked the output from the parser, and indeed it calls the TextWriter's method that accepts a params object[] argument for formatting:

private void @__Renderform1(System.Web.UI.HtmlTextWriter @__w, System.Web.UI.Control parameterContainer) {
    // ...
    @__w.Write( "{0} is {1}", "Foo", 42 );

Is that behavior documented anywhere?

jbl
  • 15,179
  • 3
  • 34
  • 101
Michiel van Oosterhout
  • 22,839
  • 15
  • 90
  • 132
  • 7
    +1 for teaching me something new. – Heinzi Sep 06 '13 at 11:30
  • 3
    @Heinzi First time I saw it, I thought it must be a bug, also because ReSharper highlighted it with a warning "Method '__ReSharper_Render' has 1 parameter(s) but is invoked with 3 argument(s)" Expression expected". – Michiel van Oosterhout Sep 06 '13 at 11:36
  • This is just classic M$FT. I've been building applications on their stack for 13 years and stuff like this always seems to crop up. I have to say, in the open-source community, you almost never see something like this that isn't documented anywhere. It may be hard to navigate because you never know which library to use, but they are documented. – Mike Perrenoud Sep 06 '13 at 12:56

3 Answers3

3

As far as I know the ASP.NET parser translates <%= %> into a call to HttpResponse.Write(string).

Maybe the <%= "{0} is {1}", "Foo", 42 %> is translated to Response.Output.Write(string format, params object[] arg), Output being of type TextWriter, which would be the explanation according to http://www.hanselman.com/blog/ASPNETResponseWriteAndResponseOutputWriteKnowTheDifference.aspx

jbl
  • 15,179
  • 3
  • 34
  • 101
  • I edited my question with the output from the parser. It calls directly into `HtmlTextWriter.Write(string format, params object[] args)`. – Michiel van Oosterhout Sep 06 '13 at 13:52
  • @michielvoo I had a look at it too. <%="Foo"%> is converted the same, whereas <% Response.Write("Foo") %> is converted to base.Response.Write("Foo") I guess @__w is the Response.Output. I will have to find a way to check ;-) – jbl Sep 06 '13 at 14:00
  • What I did was create a simple ASPX page with the render block, set debug to true in web.config, cause a compile error somewhere in the ASPX page, and then request the page. On the error page there is an option to show the compilation source, which shows you the parser generated code. – Michiel van Oosterhout Sep 06 '13 at 14:39
  • 1
    @michielvoo after a moment looking at mono sources for aspx pages compilation, I can't figure out if the same behaviour applies in mono. That's quite interesting. https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.Compilation/TemplateControlCompiler.cs#L1374 – jbl Sep 06 '13 at 16:21
3

This is an <%= %> embedded code block and exists to maintain compatibility with Classic ASP.

As you saw <%= "{0} is {1}", "Foo", 42 %> is equivalent to:

string s = string.Format("{0} is {1}", "Foo", 42);
Response.Write(s);

That behavior is documented here:

Writes a formatted string that contains the text representation of an object array to the output stream, along with any pending tab spacing. This method uses the same semantics as the String.Format method. (Overrides TextWriter.Write(String, Object[]).)

Here is where it's documented that the Code Render Block calls the Write method.

Finally, the syntax for embedded code blocks has been updated for .NET 4 as described here.

Community
  • 1
  • 1
dcaswell
  • 3,137
  • 2
  • 26
  • 25
  • +1 for all of the documentation links - but none of them specifically state that you can use an **implied** syntax in an embedded code block. – Mike Perrenoud Sep 06 '13 at 13:00
  • What implied syntax are you talking about? String.Format takes a variable number of arguments. – dcaswell Sep 06 '13 at 13:00
  • `<%= %>` is not actually an 'embedded code block', but rather a 'code render block with an inline expression'. And the documentation may state that it calls `Reponse.Write(string)`, but that method does not support formatting. The documentation doesn't connect `<%= %>` to `HtmlTextWriter`, thus the support for formatting inside these blocks is probably not widely known. Weird, no? – Michiel van Oosterhout Sep 06 '13 at 13:26
  • It's documented to have semantics similar to String.Format. I'm missing everyone's question. When I type the code into Visual Studio and click F1 for help it took me to the help for Embedded Code Blocks. – dcaswell Sep 06 '13 at 13:28
-1

This is close and perhaps related http://msdn.microsoft.com/en-us/library/586y06yf.aspx but it's not an explanation for why the <%= does it...

guymid
  • 1,186
  • 8
  • 11