Calling RenderAction in an ASP.NET MVC 4 Controller Toolbar (Multi-User Mode)

I have an HTML template string in which at various unknown points there are {{Url}} placeholders in it that refer to a specific controller / action in my application. I need to do html in these placeholders before displaying the final html in the view.

In the view, I can simply call Html.RenderAction("Action","Controller") , which returns the string I need. However , I need to call this method in the controller code, for example (this is simplified):

In the controller "Dashboard":

 var templateHtml = GetTemplateHtml(); //The following line doesn't compile var html = Html.RenderAction("Index","PowerAnalysisDashpart"); ViewBag.Html = templateHtml.Replace("{{PowerAnalysisDashpart}}",html) 

Then in the Dashboard view:

 <div id="content"> @Html.Raw(ViewBag.Html) </div> 

How can I call RenderAction to get a Rendered HTML string in a controller?

EDIT: There seems to be a confusion about what I'm trying to achieve. Basically, we need administrators to be able to create an HTML template that will effectively have frames for different pages of our application. Iframes will work, but we would prefer that all HTML be built on the server.

+4
source share
4 answers

I think you want HtmlHelper.Action , not RenderAction . RenderAction writes content to the response stream. Action returns it as a string.

http://msdn.microsoft.com/en-us/library/ee721266(v=vs.108).aspx

The action is defined in the ChildActionExtensions class, which lives in the System.Web.Mvc.Html , so your controller code will need to use this namespace.

Action returns Html as a string, while RenderAction returns void, because RenderAction writes its Html output directly to the current response stream embedded in the parent document. This is why it works in terms of, but not with, the controller.

To create an instance of HtmlHelper in MVC 4, you can use this:

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

As other commentators on related SO issues have said, this is not as intended (which is obvious due to the hacker way you have to install the HtmlHelper). I am not sure if this is much better than your alternative solution. It is better to refactor to be more MVC, as if you could, although sometimes I understand that this is not an option.

+8
source

So, I found a solution, but it is very hacks, and just has to be in a cleaner way!

I have a general partial view of "_view" that only has this in it:

 @{ Html.RenderAction("Index",(string)ViewBag.Controller); } 

I used the code from this blog: http://approache.com/blog/render-any-aspnet-mvc-actionresult-to/ to write an extension method for the ActionResult class.

Then in my controller, I do this:

 var templateHtml = GetTemplateHtml(); ViewBag.Controller = "PowerAnalysis"; var html = View("_view").Capture(ControllerContext); ViewBag.Html = htmlTemplate.Replace("{{PowerAnalysis}}", html); //Repeat for other pages return View(); 

Below is the code for the extension method that I used on the blog:

 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(); } } } 
+2
source

I think you need partial views that you can partially display in the main view

  @Html.Partial("myPartailView") 

for a link to a detailed check

http://www.codeproject.com/Tips/617361/Partial-View-in-ASP-NET-MVC-4

-2
source

To display the view as a string, you can follow the following approach:

 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(); } } 
-2
source

Source: https://habr.com/ru/post/1500269/


All Articles