ASP.NET Core MVC:实现基于动态字符串对象的HTML代码视图及模型设计求助
Looks like you're trying to render a full HTML page from a dynamic Razor template string while binding it to an Entity model in ASP.NET Core MVC. Your current approach has a couple of key issues—namely that you're passing the HTML string as a view name (which isn't how the View() method works) and the Razor syntax in your string won't be parsed natively. Let's fix this step by step:
1. Update Your Models
Keep your PageHtmlModel for passing the final rendered HTML, and your Entity model remains as-is:
public class PageHtmlModel { public string HtmlCode { get; set; } } public class Entity { private int _ID; private string _Module; private string _Explanation; private string _Situation; private string _Personel; private string _PersonelsNotes; private string _EndDate; public int id { get => _ID; set => _ID = value; } public string module { get => _Module; set => _Module = value; } public string explanation { get => _Explanation; set => _Explanation = value; } public string situation { get => _Situation; set => _Situation = value; } public string personel { get => _Personel; set => _Personel = value; } public string personels_notes { get => _PersonelsNotes; set => _PersonelsNotes = value; } public string end_date { get => _EndDate; set => _EndDate = value; } }
2. Simplify Your Data Access Layer
Update your HTML template method to return just the Razor template string (no need to wrap it in PageHtmlModel yet):
public static string GetInvoiceTemplate() { // Raw Razor template string targeting your Entity model return "@model deneme100.Models.Entity <html> <head> <link href='~/css/invoice.css' rel='stylesheet' /> </head> <body> <div class='index-box'> <table cellpadding='0' cellspacing='0'> <tr class='top'> <td colspan='2'> <table> <tr> <td class='title'> <img src='~/img/logo.png' style='width:100%; max-width:300px;' /> </td> <td> @Html.DisplayNameFor(model => model.id):@Model.id <br>@Html.DisplayNameFor(model => model.module):@Model.module <br>@Html.DisplayNameFor(model => model.explanation):@Model.explanation </td> </tr> </table> </td> </tr> <tr class='information '> <td colspan='2 '> <table> <tr> <td> @Html.DisplayNameFor(model => model.situation):@Model.situation <br>@Html.DisplayNameFor(model => model.end_date):@Model.end_date </td> <td> </td> </tr> </table> </td> </tr> <tr class='heading '> <td> @Html.DisplayNameFor(model => model.personels_notes) </td> <td></td> </tr> <tr class='item'> <td> @Model.personels_notes </td> </tr> <tr class='total '> <td></td> <td> @Html.DisplayNameFor(model => model.personel):@Model.personel </td> </tr> </table> </div> </body> </html>"; }
3. Use RazorLight to Compile the Template (Simplest Approach)
To parse the Razor syntax in your string, we'll use the popular RazorLight library (it handles template compilation and model binding out of the box):
Install the NuGet package:
Install-Package RazorLightUpdate your controller to compile the template and pass the final HTML to the view:
using RazorLight; public class HomeController : Controller { public async Task<IActionResult> PDF(int id) { // Fetch your Entity data var entity = EntityDataAccess.OneObject(new Entity() { id = id }).FirstOrDefault(); if (entity == null) { return NotFound(); } // Get the Razor template string var template = EntityDataAccess.GetInvoiceTemplate(); // Compile and render the template with your Entity model var engine = new RazorLightEngineBuilder() .UseMemoryCachingProvider() .Build(); var renderedHtml = await engine.CompileRenderStringAsync("invoiceTemplate", template, entity); // Pass the final HTML to your view return View(new PageHtmlModel { HtmlCode = renderedHtml }); } }
4. Finalize Your View
Your target view only needs to output the pre-rendered HTML (disable the layout to return a full standalone page):
@model myProject.Models.PageHtmlModel @{ ViewData["Title"] = "PDF"; Layout = null; // Disable layout to output a complete HTML page } @Html.Raw(Model.HtmlCode)
5. Keep Your Frontend JS as-Is
Your existing jQuery code for selecting the row and navigating to the PDF action doesn't need changes:
$('#myTable tbody').on('click', '#pdf', function () { if (!($(this).closest('tr').hasClass('selected'))) { table.$('tr.selected').removeClass('selected'); $(this).closest('tr').addClass('selected'); } obj = {} obj.id = $('tr.selected td').eq(0).html(); window.location = "/Home/PDF/" + obj.id; if ($(this).closest('tr').hasClass('selected')) { $(this).closest('tr').removeClass('selected'); } })
Key Notes:
- We use
@Html.Raw()to output the compiled HTML without encoding it. - RazorLight handles compiling the Razor template string, replacing
@Modelreferences with your Entity's actual data. - Disabling
Layout = nullensures the view returns a full HTML document instead of a partial view.
内容的提问来源于stack exchange,提问作者Tunahan Çolak

