NickL
NickL

Reputation: 1960

Can Steven Sanderson's Partial Request technique be used in Razor pages?

I like the idea of Steven Sanderson's Partial Requests in http://blog.stevensanderson.com/2008/10/14/partial-requests-in-aspnet-mvc/ and I'm trying to get it to work with Razor pages. Unfortunately it writes it to the top of the page, instead of where I actually want it to be in the document. I'm guessing the problem is similar to the one answered here: ASP.Net MVC 3 Razor Response.Write position but I don't know how to get around it.

Can anyone supply me with a workaround? Failing that, is there simply another good technique for rendering the contents of another action in a view, without that view having to know about the action?

Upvotes: 2

Views: 295

Answers (1)

Rich O'Kelly
Rich O'Kelly

Reputation: 41767

Yes, it is possible.

As I'm sure you're now aware the Razor view engine writes to temporary buffers before writing to the response stream, which is why when you invoke another action the markup gets written to the response out of order.

The workaround that I've used in the past is to temporarily redirect any writes to the response to a MemoryStream while you are trying to render another action, and then creating a MvcHtmlString from the contents of the MemoryStream.

So something like:

public class HttpResonseCapture : IDisposable
    {
        private readonly MemoryStream _stream = new MemoryStream();
        private readonly Stream _originalStream;
        private readonly HttpContextBase _httpContext;

        public HttpResponseCapture(HttpContextBase httpContext)
        {
            _httpContext = httpContext;
            _originalStream = httpContext.Response.OutputStream;
            httpContext.Response.OutputStream = _stream;
        }

        public MvcHtmlString ToHtmlString() 
        {
            return MvcHtmlString.Create(Encoding.Unicode.GetString(_stream.ToArray()));
        }

        public void Dispose()
        {
            _httpContext.Response.OutputStream = _originalStream;
            _stream.Dispose();
        }
    }

Can be used like so:

using (var responseCapture = new HttpResponseCapture(httpContext))
{
   // Call other action here
   var result = responseCapture.ToHtmlString();
}

Upvotes: 1

Related Questions