Ayende @ Rahien

Refunds available at head office

Another ASP.Net MVC bug: Rendering views to different output source

Take a look at the following code. What would you expect the result of this code to be?

image

Leaving aside the question of exactly what I am doing here, or why. What I thought this should do was to render the partial view into the string writer.

The method signature of Render most strongly suggest that this is what it would do. What it actually does is to render the partial view directly into the response. Following the code a bit more, it looks like you literally cannot do this.

ASP.Net MVC views are hard coded to use the current request ( ViewPage.RenderView ). I checked a bit, and without basically faking the entire HttpContext and all its associated objects, that doesn't seem to be happening.

There are two problems here:

  • The API lies about what it is doing
  • There is no simple & obvious way to get the output of a view except directly into the response.

Comments

Simone
11/11/2008 09:43 PM by
Simone

That's weird, when you supply your own textwriter the render method of the view should write to it.

It's used in testing views as well.

In my testing code there is:

        MyTextView view = new MyTextView (templatePath);

        StringWriter writer = new StringWriter();

        view.Render(null, writer);

        string rendered = writer.ToString();

And it works correctly, at least inside a test case.

Ayende Rahien
11/11/2008 09:56 PM by
Ayende Rahien

Try to execute my code.

You are going through a different code path.

Simone
11/11/2008 10:04 PM by
Simone

OMG!!!!

The WebFormView doesn't do anything with the writer parameter, it just swallows it....

that really a bug... even tho I think it cannot be changed since the webviewengine is based on the webform model.

One more reason not to use the WebFormViewEngine :)

Haacked
11/11/2008 10:17 PM by
Haacked

This is one of them tough decisions we had due to the nature of the framework we're building on. It's less than ideal, but is for the greater good eventually.

Yes, the WebFormViewEngine ignores the writer parameter. We exposed the parameter in the underlying API to encourage other view engine implementors to do the right thing and write to the writer as they render the output rather than creating one big string that they write out at the end. In part, this was to make sure that RenderPartial would work with other view engines.

Unfortunately, we can't change our own view engine to do this same thing as that would require changes to core bits of the Page class etc... MVC is built on top of ASP.NET core and we can't make changes to the core for MVC right now. Maybe when the next major framework release comes out, we can actually fix this.

However, since the WebFormViewEngine already streams output to the writer rather than generating one big string, it doesn't suffer the key problem we wanted to solve.

Simone
11/11/2008 10:36 PM by
Simone

@Haacked: maybe a compromise?

I mean, when the writer parameter is the Response then you do nothing and go like now, so no possible performances hits.

When the writer parameter is a custom one you change the response output stream calling the HttpResponse's private method "SwitchWriter" (using reflection) to supply the custom writer.

Ayende Rahien
11/12/2008 03:32 AM by
Ayende Rahien

Phil,

This means that I cannot get the view into a string.

That is a PROBLEM.

This is so because this is an incredibly common thing to do when you are playing around with composable apps and manipulating views.

At the very least, this should throw an exception about this being not supported.

Or, much better (from my point of view), is to get the framework to fake the pipeline in order to support it.

Frans Bouma
11/12/2008 08:35 AM by
Frans Bouma

I might be wrong, but isn't this still in beta? If so, why are you doing production work on this?

Torkel
11/12/2008 08:52 AM by
Torkel

Ayende,

use the Spark view engine :)

Steve Wagner
11/12/2008 03:41 PM by
Steve Wagner

I am agree with Ayende. When its not possible to do it, it should throw a exception instead of letting me standing in the rain.

Harry
11/13/2008 05:19 AM by
Harry

It has taken me a long time to find this answer.

Wow what a waste of time (+4 hours of hacking and searching).

I wish there was better documentation for ASP.net (I know it's beta - but i'm impatient :) )

Endif
11/13/2008 09:51 AM by
Endif

I spent a few hours on the same problem (see http://forums.asp.net/t/1315284.aspx) and it's pretty disappointing to hear it cannot be fixed for RTM :-(

@Haacked: Isn't there a way to "hack" it with some output caching? Something like BlockRenderer (see the link) does?

Kevin Zink
11/16/2008 11:25 PM by
Kevin Zink

Hey Everyone,

I put together a rough framework which allows you to render views to a string from a controller method in MVC Beta.

Additionally, I also put together a Rails-like RJS javascript generating framework for MVC Beta.

Check it out at www.brightmix.com/.../how-to-renderpartial-to-s... and let me know what you think.

kk
12/02/2008 09:00 AM by
kk

try this

Comments have been closed on this topic.