如何解决渲染 RazorPage,路由参数为字符串
我使用以下代码将 ASP.NET Core RazorPages 呈现为字符串:
public class RazorPagetoStringRenderer : IRazorPagetoStringRenderer
{
private readonly IRazorViewEngine razorViewEngine;
private readonly ITempDataProvider tempDataProvider;
private readonly IHttpContextAccessor httpContext;
private readonly IActionContextAccessor actionContext;
private readonly IRazorPageActivator activator;
public RazorPagetoStringRenderer(IRazorViewEngine razorViewEngine,ITempDataProvider tempDataProvider,IHttpContextAccessor httpContext,IActionContextAccessor actionContext,IRazorPageActivator activator)
{
this.razorViewEngine = razorViewEngine;
this.tempDataProvider = tempDataProvider;
this.httpContext = httpContext;
this.actionContext = actionContext;
this.activator = activator;
}
public async Task<string> RenderToStringAsync<T>(string pageName,T model) where T : PageModel
{
var context = new ActionContext(
httpContext.HttpContext,httpContext.HttpContext.GetRouteData(),actionContext.ActionContext.ActionDescriptor
);
using (var sw = new StringWriter())
{
var result = razorViewEngine.GetPage(null,pageName);
if (result.Page == null)
throw new ArgumentNullException($"The page {pageName} cannot be found.");
var view = new RazorView(razorViewEngine,activator,new List<IRazorPage>(),result.Page,HtmlEncoder.Default,new DiagnosticListener("VieWrenderService"));
var viewContext = new ViewContext(
context,view,new ViewDataDictionary<T>(new EmptyModelMetadataProvider(),new ModelStateDictionary())
{
Model = model
},new TempDataDictionary(
httpContext.HttpContext,tempDataProvider
),sw,new HtmlHelperOptions()
);
var page = (Page) result.Page;
page.PageContext = new PageContext(actionContext.ActionContext)
{
ViewData = viewContext.ViewData
};
page.ViewContext = viewContext;
activator.Activate(page,viewContext);
await view.RenderAsync(viewContext);
return sw.ToString();
}
}
}
当我这样称呼它时效果很好:
private async Task SendEmail(int orderId)
{
emailModel = new InvoiceEmailModel{InvoiceNumber = orderId};
string htmlBody = await razorPagetoStringRenderer.RenderToStringAsync("/Areas/Email/Pages/InvoiceEmail.cshtml",emailModel);
await emailSender.SendEmailAsync(UserEmail,$"Order #{orderId} Placed",htmlBody);
}
但是,如果我通过将 InvoiceEmail.cshtml 中的第一行设置为需要参数来更改我的页面:
@page "{orderId:int?}"
然后我将 InvoiceEmailModel PageModel 更改为有一个名为的新方法:
public IActionResult OnGet(int orderId)
当我像这样从浏览器访问它时它也有效:localhost:5000/Email/InvoiceEmail?orderId=5。这仅在我在 Startup.cs MapControllers() 中注释掉并将其替换为 MapRazorPages() 时才有效 - 两者似乎都不起作用。
在任何情况下,如果我删除地图 razor 页面,只留下地图控制器并尝试访问 razor 页面,每当我尝试访问 Model 属性时,都会在 Page InvoiceEmail.cshtml 中收到 NullReferenceException 并且 OnGet 方法将不会执行.
我尝试像这样设置 ModelStateDictionary:
var modelState = new ModelStateDictionary();
modelState.SetModelValue("orderId",5,"5");
然后在 ActionContext 中使用它:
var context = new ActionContext(
httpContext.HttpContext,actionContext.ActionContext.ActionDescriptor,modelState
);
但这并没有改变输出。有谁知道如何指定 orderId 页面参数并让 OnGet 方法在我从代码运行时也执行?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。