pavanarya

Let us share the knowledge

Rendering a View differently without using return View() directly

with one comment

Hi,
In this post i am planning to render a view inside the controller somewhat differently.

In general when we want to render a view from a controller’s method we will have something like this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication2.Controllers
{
    public class FirstController : Controller
    {
        //
        // GET: /First/
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Index()
        {
            return View("Index");
        }
    }
}

This is the basic syntax for rendering a view. we will have a method view() which is used to render a view.

I want to do something like this.

public class FirstController : Controller
    {
        //
        // GET: /First/

        public string Index()
        {
           string aa= RenderView.RenderViewToString(this, "Index", null);//RenderView is my custom static class that has a method RenderViewToString.
           return aa;
        }
    }

This code is in contrast with the 1st code snippet but i want this to do the same work.

Rendering a view by using Render() of IView interface
There is a method called Render() defined inside IView interface.
This method returns the html content of the view.

IView interface has a method called Render() it accepts two parameters.
1.object of ViewContext
2.object of TextWriter.

what is this ViewContext??
It encapsulates the information related to rendering a view.
It has two constructors

ViewContext();//initializes a viewcontext 
ViewContext(ControllerContext, IView, ViewDataDictionary, TempDataDictionary, TextWriter);

Parameters of the second constructor

1.ControllerContext
Controller.controllerContext
2.Iview
View to render. If we have a view name and controller object then we can get an object of Ivew as follows
In order to get the view object we are supposed to have Controller object and name of the view to render

var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
IView v=viewResult.View;

ViewEngines.Engines is used to get the list of view engines associated with the application.

3.ViewDataDictionary
Contains data(Model) that is used to render view.
We can use something like controller.ViewData.Model=objModelClass
There is a property called ViewData associated with controller object that returns ViewDataDictionary object.

4.TempDataDictionary
This contains temporary information for rendering a view. controller.TempData returns this object

5. Textwriter object that contains rendered data.

So coming to our function that returns rendered view as html string. Our custom function need three parameters.
i.object of a controller
ii.name of the view to render
iii.Model object

public static string RenderViewToString(this Controller controller, string viewName, object model)
        {

            controller.ViewData.Model = model;//assigning model to Controllers ViewDatsDictionary

            using (var sw = new StringWriter())
            {
                var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
                var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }

Complete code of the controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;

namespace MvcApplication1.Controllers
{
    public class FirstController : Controller
    {
        //
        // GET: /First/

        public string Index()
        {
           string aa= RenderView.RenderViewToString(this, "Index", null);
           return aa;
        }
    }
    class RenderView
    {

        public static string RenderViewToString( Controller controller, string viewName, object model)
        {

            controller.ViewData.Model = model;

            using (var sw = new StringWriter())
            {
                var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
                var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }
    }
}

I am having two classes. FirstController which inherits from Controller class and RenderView class that contains our method RenderViewToString.

When we execute the following url “http://localhost:11099/First/Index” in the browser.
This will execute The index method inside FirstControlelr class. This index method returns string response to the browser back.
Inside Index method we are calling our RenderViewToString as follows.

public string Index()
        {
           string aa= RenderView.RenderViewToString(this, "Index", null);
           return aa;
        }

1st parameter this corresponds to the Current controller object that is firstcontroller object.
2nd parameter corresponds to the name of the view we want to render.
3rd parameter is for model object. I am passing null because my view doesn’t need any model to render.

Index.cshtml

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Index</title>
</head>
<body>
    <div>
        Hi This is Pavan to test rendering a view.
    </div>
</body>
</html>

Thanks,
pavan

About these ads

Written by pavanarya

June 21, 2012 at 9:36 am

Posted in MVC

One Response

Subscribe to comments with RSS.

  1. [...] HI this is an extension to my previous post Rendering a View differently without using return View() directly [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 67 other followers

%d bloggers like this: