user441365
user441365

Reputation: 4024

Is there a way to get a PartialView HTML content in the controller?

I have a partial view with a controller with outputCache on as I need to cache this element.

Then I need to render this PartialView in every page, but first I need to do some string replacement.

So my question is, howdo I get a Partial View in a controller so I can manipulate the content and do some string replacement before returning it to the View?

Thanks

Upvotes: 3

Views: 5610

Answers (3)

Sandeep Phadke
Sandeep Phadke

Reputation: 882

Just wanted to share a modification to @Nico's solution, if you want to use ViewBag data from your controller action then change RenderViewToString as follows, I use controller.TempData instead of new TempDataDictionary().

public string RenderViewToString( IView view, object model)
{
    InvalidateControllerContext();
    string result = null;
    if (view != null)
    {
        StringBuilder sb = new StringBuilder();
        using (StringWriter writer = new StringWriter(sb))
        {
            // use TempData from controller
            ViewContext viewContext = new ViewContext(ControllerContext, view, 
                new ViewDataDictionary(model), this.TempData, writer);
            view.Render(viewContext, writer);
            writer.Flush();
        }
        result = sb.ToString();
    }
    return result;
}

Upvotes: 0

jrummell
jrummell

Reputation: 43067

No, don't do this. Your controller should not render your View, that's the job of the templating engine.

Pass the "replacement" values as a model to your PartialView.

public ActionResult SomeAction()
{
  SomeModelmodel = new SomeModel(); // your model
  return PartialView(model); // partial view with your model
}

And the Partial View:

@model SomeModel

<div>Replace your values with @Model.Value instead of String.Replace().</div>

Upvotes: 2

bevacqua
bevacqua

Reputation: 48476

I use these methods on my custom Controller base.

    public string RenderPartialToString(string partialViewName, object model)
    {
        InvalidateControllerContext();
        IView view = ViewEngines.Engines.FindPartialView(ControllerContext, partialViewName).View;
        string result = RenderViewToString(view, model);
        return result;
    }

    public string RenderViewToString(string viewName, object model)
    {
        InvalidateControllerContext();
        IView view = ViewEngines.Engines.FindView(ControllerContext, viewName, null).View;
        string result = RenderViewToString(view, model);
        return result;
    }

    public string RenderViewToString(IView view, object model)
    {
        InvalidateControllerContext();
        string result = null;
        if (view != null)
        {
            StringBuilder sb = new StringBuilder();
            using (StringWriter writer = new StringWriter(sb))
            {
                ViewContext viewContext = new ViewContext(ControllerContext, view, new ViewDataDictionary(model), new TempDataDictionary(), writer);
                view.Render(viewContext, writer);
                writer.Flush();
            }
            result = sb.ToString();
        }
        return result;
    }

    private void InvalidateControllerContext()
    {
        if (ControllerContext == null)
        {
            ControllerContext context = new ControllerContext(System.Web.HttpContext.Current.Request.RequestContext, this);
            ControllerContext = context;
        }
    }

The InvalidateControllerContext method is meant for the scenario where you need to instance Controllers manually in order to render partials or views outside of the context of a controller.

Upvotes: 8

Related Questions