Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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# 以编程方式将Razor页面呈现为HTML字符串 目标 我正试图在后端生成一个HTML字符串 使用HtmlToPDF库将其转换为PDF 我还希望能够在浏览器中轻松查看生成的HTML,以便进行调试/调整。只有当IsDevelopment()时,该页面才会公开 我希望它尽可能简单_C#_Asp.net Core_Razor Pages_Asp.net Core 3.1_Razorengine - Fatal编程技术网

C# 以编程方式将Razor页面呈现为HTML字符串 目标 我正试图在后端生成一个HTML字符串 使用HtmlToPDF库将其转换为PDF 我还希望能够在浏览器中轻松查看生成的HTML,以便进行调试/调整。只有当IsDevelopment()时,该页面才会公开 我希望它尽可能简单

C# 以编程方式将Razor页面呈现为HTML字符串 目标 我正试图在后端生成一个HTML字符串 使用HtmlToPDF库将其转换为PDF 我还希望能够在浏览器中轻松查看生成的HTML,以便进行调试/调整。只有当IsDevelopment()时,该页面才会公开 我希望它尽可能简单,c#,asp.net-core,razor-pages,asp.net-core-3.1,razorengine,C#,Asp.net Core,Razor Pages,Asp.net Core 3.1,Razorengine,我正在使用ASP.NETCore3.1 方法 剃刀页面 我想我应该试试新的剃须刀页面,因为它们的广告宣传非常简单 @page @使用MyProject.Pages.Pdf @模型索引模型 试验 @模型消息 namespace MyProject.Pages.Pdf { 公共类索引模型:PageModel { 私有只读MyDbContext\u context; 公共索引模型(MyDbContext上下文) { _上下文=上下文; } 公共字符串消息{get;private set;}=“C

我正在使用ASP.NETCore3.1

方法 剃刀页面 我想我应该试试新的剃须刀页面,因为它们的广告宣传非常简单

@page
@使用MyProject.Pages.Pdf
@模型索引模型
试验

@模型消息

namespace MyProject.Pages.Pdf
{
公共类索引模型:PageModel
{
私有只读MyDbContext\u context;
公共索引模型(MyDbContext上下文)
{
_上下文=上下文;
}
公共字符串消息{get;private set;}=“C#中的页面模型”;
公共异步任务OnGetAsync()
{
var count=await_context.Foos.CountAsync();
Message+=$“服务器时间为{DateTime.Now},Foo计数为{count}”;
返回页();
}
}
}
这在浏览器中工作-耶

呈现并获取HTML字符串 我发现它似乎做了我想要的

但问题就从这里开始:(

问题 首先,我觉得很奇怪,当你通过
\u razorViewEngine.FindPage
查找页面时,它不知道如何填充
ViewContext
Model
。我认为
IndexModel
的工作就是填充这些页面。我希望有可能向ASP.NET索要
IndexModel
页面就是这样

无论如何……下一个问题。为了呈现页面,我必须手动创建一个
ViewContext
,我必须为它提供一个
模型
。但是页面就是模型,因为它是一个页面,所以它不是一个简单的ViewModel。它依赖于DI,需要
OnGetAsync()
将被执行以填充模型。这几乎是第22条军规

我还尝试通过
\u razorViewEngine.FindView
获取视图而不是页面,但这也需要一个模型,所以我们回到了第22条军规

另一个问题。调试/调整页面的目的是轻松查看生成的内容。但是如果我必须在
索引模型
之外创建
模型
,那么它就不再代表某个服务中实际生成的内容


所有这些都让我想知道我是否走对了路。或者我遗漏了什么吗?

请参考以下步骤来渲染字符串的局部视图:

  • 将名为IRazorPartialToStringRenderer.cs的接口添加到服务文件夹

     public interface IRazorPartialToStringRenderer
     {
         Task<string> RenderPartialToStringAsync<TModel>(string partialName, TModel model);
     }
    
  • 使用RenderPartialToStringAsync()方法将Razor页面呈现为HTML字符串:

     public class ContactModel : PageModel
     {
         private readonly IRazorPartialToStringRenderer _renderer;
         public ContactModel(IRazorPartialToStringRenderer renderer)
         {
             _renderer = renderer; 
         }
         public void OnGet()
         { 
         }
         [BindProperty]
         public ContactForm ContactForm { get; set; }
         [TempData]
         public string PostResult { get; set; }
    
         public async Task<IActionResult> OnPostAsync()
         {
             var body = await _renderer.RenderPartialToStringAsync("_ContactEmailPartial", ContactForm);  //transfer model to the partial view, and then render the Partial view to string.
             PostResult = "Check your specified pickup directory";
             return RedirectToPage();
         }
     }
     public class ContactForm
     {
         public string Email { get; set; }
         public string Message { get; set; }
         public string Name { get; set; }
         public string Subject { get; set; }
         public Priority Priority { get; set; }
     }
     public enum Priority
     {
         Low, Medium, High
     }
    
    公共类联系人模型:页面模型
    {
    专用只读IRazorPartialToStringRenderer\u渲染器;
    公共联系人模型(IRazorPartialToStringRenderer)
    {
    _渲染器=渲染器;
    }
    公共互联网
    { 
    }
    [BindProperty]
    公共联系人表单联系人表单{get;set;}
    [临时数据]
    公共字符串PostResult{get;set;}
    公共异步任务OnPostAsync()
    {
    var body=wait _renderer.RenderPartialToStringAsync(“_ContactEmailPartial”,ContactForm);//将模型传输到局部视图,然后将局部视图渲染为字符串。
    PostResult=“检查指定的收货目录”;
    返回重定向Topage();
    }
    }
    公开课联络表格
    {
    公共字符串电子邮件{get;set;}
    公共字符串消息{get;set;}
    公共字符串名称{get;set;}
    公共字符串主题{get;set;}
    公共优先级{get;set;}
    }
    公共枚举优先级
    {
    低、中、高
    }
    
  • 调试屏幕截图如下所示:


    更多详细步骤,请查看此博客。

    我成功破解了它!毕竟我走错了路…解决方案是使用
    视图组件。
    。但它仍然很时髦

    多亏了

    • 还有很多
    解决方案 已将PageModel转换为ViewComponent
    名称空间MyProject.ViewComponents
    {
    公共类MyViewComponent:ViewComponent
    {
    私有只读MyDbContext\u context;
    公共MyViewComponent(MyDbContext上下文)
    {
    _上下文=上下文;
    }
    公共异步任务InvokeAsync()
    {
    var count=await_context.Foos.CountAsync();
    var message=$“服务器时间为{DateTime.Now},Foo计数为{count}”;
    返回视图(消息);
    }
    }
    }
    
    并且视图被放置在页面/Shared/Components/My/Default.cshtml

    @model string
    
    <h2>Test</h2>
    <p>
        @Model
    </p>
    
    与RouteData 来自控制器
    [HttpGet]
    公共异步任务Get()
    {
    var html=await_renderViewComponentService
    .RenderViewComponentToStringAsync();
    //用html做些什么
    返回Ok(新的{html});
    }
    
    用FromRoute
    [HttpGet(“{id}”)]
    公共异步任务Get([FromRoute]int id)
    {
    var html=await_renderViewComponentService
    .RenderViewComponentToStringAsync(id);
    //用html做些什么
    返回Ok(新的{html});
    }
    
    奇怪的 非常不幸的是,注入的
    IViewComponentThelper
    无法开箱即用

    所以我们必须做这件非常不直观的事情来让它工作

    (\u viewComponentHelper作为IViewContextAware)。上下文化(viewContext);
    
    这导致了一系列奇怪的事情,比如伪
    ActionContext
    ViewContext
    ,它们需要
    TextWriter
    ,但它没有任何用途!事实上,hole
    ViewContext
    根本没有使用。它只需要存在:(

    还有
    空视图
    …用于
     public class ContactModel : PageModel
     {
         private readonly IRazorPartialToStringRenderer _renderer;
         public ContactModel(IRazorPartialToStringRenderer renderer)
         {
             _renderer = renderer; 
         }
         public void OnGet()
         { 
         }
         [BindProperty]
         public ContactForm ContactForm { get; set; }
         [TempData]
         public string PostResult { get; set; }
    
         public async Task<IActionResult> OnPostAsync()
         {
             var body = await _renderer.RenderPartialToStringAsync("_ContactEmailPartial", ContactForm);  //transfer model to the partial view, and then render the Partial view to string.
             PostResult = "Check your specified pickup directory";
             return RedirectToPage();
         }
     }
     public class ContactForm
     {
         public string Email { get; set; }
         public string Message { get; set; }
         public string Name { get; set; }
         public string Subject { get; set; }
         public Priority Priority { get; set; }
     }
     public enum Priority
     {
         Low, Medium, High
     }
    
    @model string
    
    <h2>Test</h2>
    <p>
        @Model
    </p>
    
    @page
    @using MyProject.ViewComponents
    
    @await Component.InvokeAsync(typeof(MyViewComponent))
    
    @page "{id}"
    @using MyProject.ViewComponents
    
    @await Component.InvokeAsync(typeof(MyViewComponent), RouteData.Values["id"])