Introduction
In this session, we will briefly discuss how to bind View.cshtml DOM content into _Layout.cshtml using Razor Engine.
Razor Engine is a free Microsoft tool that you can download from NuGet Package Manager. It contains the collection of methods and properties. We have an option to bind one View into another using “@Model.Parameter”.
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- </head>
- <body>
- <table class="menu">
- <tr>
- <td><h1>Report Header</h1></td>
- <td></td>
- </tr>
- </table>
- @Model.DynamicView
- </body>
- </html>
The above code is a structure where we will insert a set of code from another View using _Layout.cshtml.
Create Home Controller
Here, we have created the Home Controller and Action Method called as Generate. Create the View for the method.
Create new View
Right-click on the method, select “Add View”. A new popup window will appear. Click “OK”.
- public class HomeController : Controller
- {
- public ActionResult Generate()
- {
- return View();
- }
-
- }
Create Generate.cshtml in View
Create the View from the Controller. Here, I have created the View called Generate.cshtml.
You can see that I have included the button click event to call Razor Engine method.
- @{
- ViewBag.Title = "Generate";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
-
- <h2>PDF Templates</h2><br />
-
- <div>
- @Html.ActionLink("Template 1", "GenerateReport", "HOME", new { @class = "btn btn-primary" }) <b>View Name: PDF</b>
- </div>
-
- <div>
- </div>
RouteConfig.cs
Change the “Route Configuration” in class file to redirect your current controller at run-time.
- public class RouteConfig
- {
- public static void RegisterRoutes(RouteCollection routes)
- {
- routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
- routes.MapRoute(
- name: "Default",
- url: "{controller}/{action}/{id}",
- defaults: new { controller = "Home", action = "Generate", id = UrlParameter.Optional });
- }
- }
For example, change your own control name in the “controller” attribute and change the “action”.
Create _LayoutReport.cshtml in Shared View
The _Layout.cshtml file has been created for the report and it is named as _LayoutReport.cshtml.
In the below code, we have mentioned the Model property called “@Model.MyView”. This is used to bind the View into _Layout file using Razor Engine in C#.
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <style type="text/css">
- .menu {
- background-color: #8383ff;
- color: white;
- width: 100%;
- height: 100px;
- }
-
- td {
- width: 30%;
- padding-left: 15px;
- }
- </style>
- </head>
- <body>
- <table class="menu">
- <tr>
- <td>
-
- </td>
- <td><h1>Report Header</h1></td>
- <td></td>
- </tr>
- </table>
- @Model.MyView
- </body>
- </html>
Create PDFSummary.cshtml View
Here is my own template that is used to show the content along with the input model.
- <h4>Number</h4>
- <table cellpadding="10" cellspacing="10">
- <tr>
- <td>Project Number: </td>
- <td>@Model.ProjectNumber</td>
- </tr>
- <tr>
- <td>Project Name:</td>
- <td>@Model.ProjectName</td>
- </tr>
- <tr>
- <td>Element Number:</td>
- <td>@Model.ElementNumber</td>
- </tr>
- <tr>
- <td>Element Name:</td>
- <td>@Model.ElementName</td>
- </tr>
- </table>
- @if (Model.IsShowContent)
- {
- <a href="https://www.google.co.in/">Click Here</a>
- }
We have included the Boolean operation to enable/disable the content in page. For example, if the “Model.IsShowContent” is “True”, you will see the content on page else it won’t appear.
Create function in Controller
We have created the function called “GenerateReport()”. This is used to pass the Model from Controller to Razor Engine Method.
- public class HomeController : Controller
- {
- public ProjectModel projectModel = new ProjectModel();
-
- public ActionResult Generate()
- {
- return View();
- }
-
- public void GenerateReport()
- {
- try
- {
- projectModel = projectModel.TempModel("proj1234");
- RazorViewEngineFormat.RenderEngineToString(projectModel);
- }
- catch (Exception ex)
- {
- }
- }
- }
In the above function, I have implemented the Controller with the Model data. You can see that we have referred the method called as “TempModel”. The model will fetch a set of data from the database.
Create a new Model
This static method is used to play with data around Razor Engine functionality.
- public class ProjectModel
- {
-
- #region "Public Property"
-
-
-
-
- public string ProjectNumber { get; set; }
-
-
-
-
- public string ProjectName { get; set; }
-
-
-
-
- public string ElementNumber { get; set; }
-
-
-
-
- public string ElementName { get; set; }
-
-
-
-
- public bool IsShowContent { get; set; }
-
- #endregion
-
- #region "Public Method"
-
- public ProjectModel TempModel(string ProjectID)
- {
- ProjectModel projectModel = new ProjectModel();
- projectModel.ProjectNumber = "prj1254215";
- projectModel.ProjectName = "Project Audit";
- projectModel.ElementNumber = "154-154-15454";
- projectModel.ElementName = "Test element";
- projectModel.IsShowContent = true;
- return projectModel;
- }
- #endregion
-
- }
The above “ProjectModel” class contains Properties and Methods.
Convert Razor Engine ToString
This is the Razor Engine method, which is used to append view.cshtml into _Layout.cshtml file. Make sure, you have included the RazorEngine.dll in NuGet Package Manager.
- public static void RenderEngineToString(object model)
- {
- try
- {
- string emailHtmlBody = string.Empty;
- GenerateFile generateFile = new GenerateFile();
- string reportHeader = File.ReadAllText(HttpContext.Current.Server.MapPath("~/Views/Shared/_LayoutReport.cshtml"));
- HtmlString tableValue = new HtmlString(File.ReadAllText(HttpContext.Current.Server.MapPath("~/Views/Home/PDFSummary.cshtml")));
- string result = Razor.Parse(reportHeader, new { MyView = tableValue });
- string htmlCompression = HttpUtility.HtmlDecode(result);
- using (TemplateService templateService = new TemplateService())
- {
- emailHtmlBody = templateService.Parse(htmlCompression, model, null, null);
- }
- generateFile.DownloadPDF(emailHtmlBody.ToString());
- }
- catch (Exception ex)
- {
-
- }
- }
In the above code,
- Collecting _Layout object model from cshtml and assigned to reportHeader (string property).
- The View object model content collected from cshtml and assigned to tableValue (HtmlString Property)
- Using Razor.Parse() method the View content will be concatenated into Layout file.
- The template service is used to assign the model property value to model attributes.
SCREENSHOT
In the screenshot, I have marked the Model property where we are going to bind the dynamic Views.
View DOM Object
This is “*.cshtml” file, which contains the collection of tags and parameters.
Now, let us bind the below Document Object Model into _Layout.cshtml file.
Also, the “Template Service” will bind the all model property values into Model attributes through “Parse” model.
OUTPUT
Eventually, the final output looks like below.
Please leave your comment if you find any issues or want to give feedback on this article.