1

I am trying to dynamically render pages from database. The view looks like this

@model MyModel

@{
    ViewBag.Title = Model.Title;
    Layout = Layout = "~/Views/Shared/_PageInnerLayout.cshtml";
}

@MvcHtmlString.Create(Model.Content)

MyModel has just 3 properties; Id, Title and Content

If the Content has just HTML, the view renders just fine. But in some cases, I need to render partials too. So Content may contain code like

@{
    Html.RenderPartial("_FooterPartial");
}

This does not work. Its being rendered literally, like shown in the image below

Example of rendered page

How do I fix this so that the page is rendered properly?

hutchonoid
  • 32,982
  • 15
  • 99
  • 104
Vivek
  • 382
  • 4
  • 12
  • you can add flag for example `IsPartialContent` to model, and if it is true then render partial manualy, also you can see on [razorgenerator](http://razorgenerator.codeplex.com/) – Grundy Dec 07 '13 at 07:00
  • @Grundy I didn't quite understand your answer. Can you please elaborate? – Vivek Dec 07 '13 at 07:08
  • I misunderstood, I thought that the content can only be html or a line `renderpartial` with no other html code – Grundy Dec 07 '13 at 07:12
  • i think template for [razorengine](http://razorengine.codeplex.com/) what you need – Grundy Dec 07 '13 at 08:49
  • 1
    `@MvcHtmlString.Create` put string in output as is, so if you want put not only html you must process your `Model.Content` for example in razor engine, and output result string – Grundy Dec 07 '13 at 14:05

2 Answers2

1

The problem is in the difference between Html.RenderPartial and Html.Partial helper methods. RenderPartial directly write the result to HttpContext.Response while Partial return it as a MvcHtmlString. You need to replace the RenderPartial with Partial and maybe the RenderAction with Action.

Edited:

You need to render the content if contains the razor view scripts. If so it means you are actually storing the views or partial views inside the database. You can create a new VirtualPathProvider to help loading the views from the database. For more information see ASP.NET MVC load the Razor views from database and ASP.NET MVC and virtual view

Community
  • 1
  • 1
Kambiz Shahim
  • 2,560
  • 14
  • 21
  • @Vivek You need to render the content of `Model.Content` as a view if it contains the razor view scripts, inside the controller's action before pass it to view. – Kambiz Shahim Dec 07 '13 at 14:16
  • Well, it didn't work. I implemented a `VirtualPathProvider` and it still wouldn't render Razor Code – Vivek Dec 09 '13 at 08:49
0

I tried doing this with VirtualPathProvider, but it didn't work.

Finally what I did was to write the Content from database into a temporary view and then render the view. It worked

public ActionResult DynamicPage(int id) {
  var dynamicPage = new PagesContext().Pages.FirstOrDefault(s => s.Id == id);

  string webroot = Server.MapPath("~").TrimEnd('\\');
  string fileName = webroot + "\\Views\\\\Solutions\\Temp.cshtml";

  System.IO.File.WriteAllText(fileName, dynamicPage.Content);
  return View("Temp");
}

Here, the Content property of the dynamicPage containts HTML(including Razor code)

Vivek
  • 382
  • 4
  • 12
  • I beg to disagree, this solution has performance issue and it is not thread safe also. The multiple requests executing in the multiple threads try to write to a single file leads to the synchronization issues. – Kambiz Shahim Dec 09 '13 at 22:36
  • @KambizShahim Yes. That is an issue. Any suggestions please? – Vivek Dec 10 '13 at 11:15