1
我是MVC2.0的新手。我使用下面的代碼來捕獲HTML並將其作爲字符串返回。但是這在MVC1.0和.NET 3.5框架中工作正常。最近我將代碼升級到.NET 4.0和MVC 2.0。現在這不再起作用,上下文返回null。當我探索我看到兩個錯誤 1.「此操作需要IIS集成管道模式。」 2.OutputStream = 'response.OutputStream' 扔類型system.Web.HttpException」的例外在MVC2.0中捕獲HTML爲字符串
這裏,調用函數
var htmlstring = this.CaptureActionHtml(new PdfController(_paService, _configService), c => (ViewResult)paController.GetHTML(p));
//和捕獲方法。
/// <summary>
/// Captures the HTML output by a controller action that returns a ViewResult
/// </summary>
/// <typeparam name="TController">The type of controller to execute the action on</typeparam>
/// <param name="controller">The current controller</param>
/// <param name="targetController">The controller which has the action to execute</param>
/// <param name="action">The action to execute</param>
/// <returns>The HTML output from the view</returns>
public static string CaptureActionHtml<TController>(
this Controller controller,
TController targetController,
Func<TController, ViewResult> action)
where TController : Controller
{
return controller.CaptureActionHtml(targetController, null, action);
}
/// <summary>
/// Captures the HTML output by a controller action that returns a ViewResult
/// </summary>
/// <typeparam name="TController">The type of controller to execute the action on</typeparam>
/// <param name="controller">The current controller</param>
/// <param name="targetController">The controller which has the action to execute</param>
/// <param name="masterPageName">The name of the master page for the view</param>
/// <param name="action">The action to execute</param>
/// <returns>The HTML output from the view</returns>
public static string CaptureActionHtml<TController>(
this Controller controller,
TController targetController,
string masterPageName,
Func<TController, ViewResult> 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 = System.Web.HttpContext.Current;
var writer = new StringWriter();
var response = new HttpResponse(writer);
var context = new HttpContext(existingContext.Request, response) {User = existingContext.User};
System.Web.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);
// restore the old route data
controllerContext.RouteData.Values["controller"] = oldController;
// restore the old context
System.Web.HttpContext.Current = existingContext;
return writer.ToString();
}
我發現周圍的工作..但在另外一個問題。該模型未經過view..Here襲擊是更新的代碼
public static string CaptureActionHtml<TController>(this Controller controller, TController targetController, string masterPageName, Func<TController, ViewResult> 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);
var viewContext = new ViewContext(controllerContext, viewResult.View, targetController.ViewData, 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();
}
任何建議將是很有益的。 。