ASP.NET MVC中是否有与Server.Execute()等效的内容?
显然只适用于传统的webforms .aspx页面。
更新 我需要从同一控制器中的不同操作中获取呈现的HTML以生成PDF。也许有一种方法可以在不将html输出到响应流的情况下执行View?
答案 0 :(得分:2)
看看这个解决方案:
我用它来生成局部视图并且它有效。你必须切换到局部,但不应该是问题。
修改强>
我做了一些修正,使用了反射器并使用了之前问题的解决方案。这段代码看起来更好。视图渲染引擎与HttpContext.Current紧密相关,因此我们必须做一些黑客攻击:
/// <summary>Renders a view to string.</summary>
public static string RenderViewToString(this Controller controller,
string viewName, object viewData)
{
//Getting current response
var response = HttpContext.Current.Response;
//Flushing
response.Flush();
//Finding rendered view
var view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName).View;
//Creating view context
var viewContext = new ViewContext(controller.ControllerContext, view,
controller.ViewData, controller.TempData);
//Since RenderView goes straight to HttpContext.Current, we have to filter and cut out our view
var oldFilter = response.Filter;
Stream filter = new MemoryStream(); ;
try
{
response.Filter = filter;
viewContext.View.Render(viewContext, null);
response.Flush();
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally
{
filter.Dispose();
response.Filter = oldFilter;
}
}
它应该很容易转换为允许渲染View(将ViewEngines.Engines.FindPartialView更改为ViewEngines.Engines.FindView)。我没有看到更好的解决方案。
答案 1 :(得分:0)
MVC中的Server.Execute等效于简单地实例化所需的控制器并执行操作方法。
public ActionResult EntryAction()
{
ProductController pc = new ProductController();
return pc.Index();
}
当然,如果所需的操作位于同一个控制器上,您可以跳过第一步。
答案 2 :(得分:0)
非常感谢您的RenderViewToString代码段。我必须进行一些更改,然后将其集成到我们的基本控制器中,但它的效果非常好。
/// <summary>Renders a view to string.</summary>
public string RenderViewToString(ViewResult viewResult)
{
//Getting current response
//var response = HttpContext.Current.Response;
var response = Response;
//Flushing
response.Flush();
//Finding rendered view
var view = ViewEngines.Engines.FindView(ControllerContext, viewResult.ViewName, viewResult.MasterName).View;
//Creating view context
var viewContext = new ViewContext(ControllerContext, view,
ViewData, TempData);
//Since RenderView goes straight to HttpContext.Current, we have to filter and cut out our view
var oldFilter = response.Filter;
Stream filter = new MemoryStream();
try
{
response.Filter = filter;
viewContext.View.Render(viewContext, null);
response.Flush();
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally
{
filter.Dispose();
response.Filter = oldFilter;
}
}
答案 3 :(得分:0)
我已经以MVC的方式实现了这一点,它适用于所有结果类型。包括文件下载。
我创建了一个自定义ActionResult ExecuteUrlResult ,并在BaseController中创建了两个 Helper方法。
ExecuteUrlResult
public class ExecuteUrlResult : ActionResult
{
public string Url { get; protected set; }
public bool PreserveForm { get; protected set; }
public ExecuteUrlResult(string url)
{
this.Url = url;
}
public ExecuteUrlResult(string url, bool preserveForm)
{
this.Url = url;
this.PreserveForm = preserveForm;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Server.Execute(this.Url, this.PreserveForm);
}
}
帮助方法
protected internal ExecuteUrlResult ExecuteUrl(string url)
{
return new ExecuteUrlResult(url);
}
protected internal ExecuteUrlResult ExecuteUrl(string url, bool preserveForm)
{
return new ExecuteUrlResult(url, preserveForm);
}