Reputation: 4024
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
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
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
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 Controller
s manually in order to render partials or views outside of the context of a controller.
Upvotes: 8