I was attempting to add the functionality of a pdfresult into my site to generate pdfs in MVC, and I stumbled over this great post by Jim Zimmerman but it didnt work for me as I believe some changes that have come in MVC 2 have broken it. I have made some changes below that will get to work if anybody else needs it go for it.
public static string CaptureActionHtml(
this Controller controller,
TController targetController,
string masterPageName,
Func action)
where TController : Controller
{
if (controller == null)
{
throw new ArgumentNullException(“controller”);
}
if (targetController == null)
{
throw new ArgumentNullException(“targetController”);
}
if (action == null)
{
throw new ArgumentNullException(“action”);
}
// pass the current controller context to orderController
var controllerContext = controller.ControllerContext;
targetController.ControllerContext = controllerContext;// replace the current context with a new context that writes to a string writer
var existingContext = HttpContext.Current;
var writer = new StringWriter();
var response = new HttpResponse(writer);
var context = new HttpContext(existingContext.Request, response) { User = existingContext.User };
HttpContext.Current = context;// execute the action
var viewResult = action(targetController);// change the master page name
if (masterPageName != null)
{
viewResult.MasterName = masterPageName;
}// we have to set the controller route value to the name of the controller we want to execute
// because the ViewLocator class uses this to find the correct view
var oldController = controllerContext.RouteData.Values[“controller”];
controllerContext.RouteData.Values[“controller”] = typeof(TController).Name.Replace(“Controller”, “”);// execute the result
viewResult.ExecuteResult(controllerContext);StringWriter sw = new StringWriter();
var viewContext = new ViewContext(controllerContext, viewResult.View, new ViewDataDictionary(controllerContext.Controller.ViewData.Model), new TempDataDictionary(), sw);viewResult.View.Render(viewContext, HttpContext.Current.Response.Output);
response.Flush();// restore the old route data
controllerContext.RouteData.Values[“controller”] = oldController;// restore the old context
HttpContext.Current = existingContext;return sw.ToString();
}
Jul 05, 2010 @ 20:06:30
Hi James, Thanks for this update. One problem was that my model was not coming through to the view so I replaced the line
var viewContext = new ViewContext(controllerContext, viewResult.View, new ViewDataDictionary(controllerContext.Controller.ViewData.Model), new TempDataDictionary(), sw);
with
var viewContext = new ViewContext(controllerContext, viewResult.View, targetController.ViewData, new TempDataDictionary(), sw);
and it all seems to work ok
Apr 06, 2011 @ 01:56:53
Hi,
I too have the same problem.. I replaced the code as per you r suggestion.. still the model is not passed to the view.. any help would be great..
Mar 25, 2011 @ 23:54:40
Hi, Thanks for your solution. I have this updated solution in VS2010 with MVC2, but it seems to give me same problem as in previous solution. Here is what I get when I debug or call the CaptureActionHtml method. Your help is appreciated! thanks!
Microsoft Visual Studio
—————————
File Load
Some bytes have been replaced with the Unicode substitution character while loading file C:\Symbols\RSCC\src\source\ASP.NET_MVC\2.0\DEVDIV\depot\devdiv\feature\Mvc\main\src\SystemWebMvc\Mvc\ControllerActionInvoker.cs\64\ControllerActionInvoker.cs with Unicode (UTF-8) encoding. Saving the file will not preserve the original file contents.
—————————
OK
Jun 25, 2011 @ 05:15:22
Hello arckal,
i am also using this captionactionhtml method in VS 2010 and MVC 2. I am having the same issues with Captionactionhtml. Just wondering did u figure the issue? I would really appreciate your help. Please help me regarding this issue. Thank you very much.
Jun 25, 2011 @ 05:34:29
Hi,
I was looking for ActionResult (View) output to string, so I thought using of this solution and it did not worked for me, but later I have used another solution which worked for me. I apologize for confusion.