Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在控制器ASP.NET MVC 4中为仪表板(多)视图调用RenderAction_C#_Asp.net Mvc_Asp.net Mvc 4 - Fatal编程技术网

C# 在控制器ASP.NET MVC 4中为仪表板(多)视图调用RenderAction

C# 在控制器ASP.NET MVC 4中为仪表板(多)视图调用RenderAction,c#,asp.net-mvc,asp.net-mvc-4,C#,Asp.net Mvc,Asp.net Mvc 4,我有一个模板HTML字符串,它在不同的未知点上有{{Url}}占位符,这些占位符与我的应用程序中的某些控制器/操作有关。我需要做的是在视图中呈现最终html之前,将html呈现到这些占位符中 在一个视图中,我可以简单地调用Html.RenderAction(“Action”,“Controller”),它返回我需要的字符串但是,我需要在控制器代码中调用此方法,例如(这是简化的): 在“仪表板”控制器中: var templateHtml = GetTemplateHtml(); //The f

我有一个模板HTML字符串,它在不同的未知点上有{{Url}}占位符,这些占位符与我的应用程序中的某些控制器/操作有关。我需要做的是在视图中呈现最终html之前,将html呈现到这些占位符中

在一个视图中,我可以简单地调用
Html.RenderAction(“Action”,“Controller”)
,它返回我需要的字符串但是,我需要在控制器代码中调用此方法,例如(这是简化的):

在“仪表板”控制器中:

var templateHtml = GetTemplateHtml();

//The following line doesn't compile
var html = Html.RenderAction("Index","PowerAnalysisDashpart");

ViewBag.Html = templateHtml.Replace("{{PowerAnalysisDashpart}}",html)
然后在“仪表板视图”中:


@Html.Raw(ViewBag.Html)
如何调用“RenderAction”在控制器中获取呈现的HTML字符串

编辑:
人们似乎对我试图实现的目标感到困惑。基本上,我们需要管理员能够创建一个HTML模板,它将有效地为我们的应用程序的各种不同页面提供框架。iFrame可以工作,但我们更喜欢在服务器上构建所有HTML。

我认为您需要局部视图,您可以在主视图中呈现局部视图

 @Html.Partial("myPartailView")
详细信息检查链接


要将视图渲染为字符串,可以遵循以下方法:

var html = RenderRazorViewToString("viewName",model); //pass model if you are binding model in view


// It will return your view as string
[NonAction]
public string RenderRazorViewToString(string viewName, object model)
{
    ViewData.Model = model;
    using (var sw = new StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);
        viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
        return sw.GetStringBuilder().ToString();
    }
}

我想你想要的是
HtmlHelper.Action
而不是
RenderAction
<代码>渲染将内容写入响应流<代码>操作将其作为字符串返回

动作在
ChildActionExtensions
类中定义,该类位于
System.Web.Mvc.Html
命名空间中,因此控制器代码需要使用该命名空间

Action
以字符串形式返回Html,而
RenderAction
返回void,因为
RenderAction
将其Html输出直接写入与父文档内联的当前响应流。这就是为什么它从视图而不是控制器工作

要在MVC 4中创建HtmlHelper实例,可以使用以下方法:

HtmlHelper helper = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView(ControllerContext, "Index"), new ViewDataDictionary(), new TempDataDictionary(), new StringWriter()), new ViewPage());

正如其他评论员在相关的SO问题上所说的,这并不是真正想要的(这一点很明显,您必须以黑客的方式实例化HtmlHelper)。我不确定这比你的替代方案好多少。如果可以的话,最好重构成更像MVC的样子,尽管我有时意识到这不是一个选项。

因此,找到了一个解决方案,但它非常粗糙,而且必须有一个更干净的方法

我有一个共享的局部视图“_view”,其中只有以下内容:

@{ Html.RenderAction("Index",(string)ViewBag.Controller); }
我使用了这个博客中的代码:为ActionResult类编写一个扩展方法

然后在控制器中执行以下操作:

var templateHtml = GetTemplateHtml();
ViewBag.Controller = "PowerAnalysis";
var html = View("_view").Capture(ControllerContext);
ViewBag.Html = htmlTemplate.Replace("{{PowerAnalysis}}", html);

//Repeat for other pages

return View();
下面是我在博客中使用的扩展方法的代码:

public class ResponseCapture : IDisposable {
        private readonly HttpResponseBase response;
        private readonly TextWriter originalWriter;
        private StringWriter localWriter;
        public ResponseCapture(HttpResponseBase response) {
            this.response = response;
            originalWriter = response.Output;
            localWriter = new StringWriter();
            response.Output = localWriter;
        }
        public override string ToString() {
            localWriter.Flush();
            return localWriter.ToString();
        }
        public void Dispose() {
            if (localWriter != null) {
                localWriter.Dispose();
                localWriter = null;
                response.Output = originalWriter;
            }
        }
    }


    public static class ActionResultExtensions {
        public static string Capture(this ActionResult result, ControllerContext controllerContext) {
            using (var it = new ResponseCapture(controllerContext.RequestContext.HttpContext.Response)) {
                result.ExecuteResult(controllerContext);
                return it.ToString();
            }
        }
    }

这没有抓住重点。请仔细阅读问题。我希望从另一个控制器/操作获取整个HTML字符串,以便请求通过正常路径(授权等)。我对为每个子视图重建模型不感兴趣。你能澄清一下吗?我在HtmlHelper上没有看到“.Action”方法。RenderAction在视图中可以正常工作,但在控制器中不行。Action方法是一种在HtmlHelper上运行的扩展方法。If在ChildActionExtensions类中定义,如我提供的链接中所述(在namespace System.Web.Mvc.Html中,因此您需要在控制器代码中为该名称空间使用语句)。好的,看起来这样做是正确的。但是,如何在控制器中获取HtmlHeper对象的实例?它需要构造函数中的各种参数(ViewDataContainer等)?它有一个公共构造函数,所以您应该能够使用它。顺便说一下,虽然我可以看到您正在尝试做什么以及为什么要这样做,但如果可以的话,最好调整代码以使用部分视图。我认为您正在采取的方法是通过将UI与业务逻辑相结合来打破MVC模式。值得检查:
public class ResponseCapture : IDisposable {
        private readonly HttpResponseBase response;
        private readonly TextWriter originalWriter;
        private StringWriter localWriter;
        public ResponseCapture(HttpResponseBase response) {
            this.response = response;
            originalWriter = response.Output;
            localWriter = new StringWriter();
            response.Output = localWriter;
        }
        public override string ToString() {
            localWriter.Flush();
            return localWriter.ToString();
        }
        public void Dispose() {
            if (localWriter != null) {
                localWriter.Dispose();
                localWriter = null;
                response.Output = originalWriter;
            }
        }
    }


    public static class ActionResultExtensions {
        public static string Capture(this ActionResult result, ControllerContext controllerContext) {
            using (var it = new ResponseCapture(controllerContext.RequestContext.HttpContext.Response)) {
                result.ExecuteResult(controllerContext);
                return it.ToString();
            }
        }
    }