我目前正忙于构建一个使用Razor模板系统提供电子邮件模板的电子邮件引擎。我昨天发布了此question,并解决了该问题。
现在的问题似乎是,当我在视图中包含局部视图时,找不到该视图。我试图将局部视图包含在我的视图中,如下所示:
@await Html.PartialAsync("~/Views/Shared/EmailButton.cshtml", new EmailButtonViewModel("Confirm Account", "https://google.com"))
我尝试删除~
没有任何效果,我使用了反射来获取通往部分视图的完整路径,并将其传递到PartialAsync
上,但这也不起作用。我尝试将整个路径添加到startup.cs
中的共享视图文件夹中,如下所示:
services.Configure<RazorViewEngineOptions>(o =>
{
var dir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
o.ViewLocationFormats.Add("~/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
});
在上面的代码中,我尝试将~
替换为dir
,以指定该文件夹的整个位置也无效。我的电子邮件模板位于.NET Core类库中,并且它们的所有Build Action
都设置为Content
,Copy to output directory
都设置为Copy always
我不确定还有什么尝试。
我的startup.cs
如下所示(为简洁起见,删除了不必要的部分):
services.AddScoped<IRazorViewToStringRenderer, RazorViewToStringRenderer>();
services.AddScoped<Email>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.Configure<RazorViewEngineOptions>(o =>
{
var dir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
o.ViewLocationFormats.Add("~/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
});
渲染视图并将其转换为字符串的代码如下:
await _razorViewToStringRenderer.RenderViewToStringAsync("Views/Emails/NewOrder/NewOrder.cshtml", newOrderModel);
RenderViewToStringAsync
如下:
public async Task<string> RenderViewToStringAsync<TModel>(string viewName, TModel model)
{
var actionContext = GetActionContext();
var view = FindView(actionContext, viewName);
using (var output = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
view,
new ViewDataDictionary<TModel>(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary())
{
Model = model
},
new TempDataDictionary(
actionContext.HttpContext,
_tempDataProvider),
output,
new HtmlHelperOptions());
await view.RenderAsync(viewContext);
return output.ToString();
}
}
我的FindView
代码为
private IView FindView(ActionContext actionContext, string viewName)
{
var dir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var getViewResult = _viewEngine.GetView(executingFilePath: dir, viewPath: viewName, isMainPage: true);
if (getViewResult.Success)
{
return getViewResult.View;
}
var findViewResult = _viewEngine.FindView(actionContext, viewName, isMainPage: true);
if (findViewResult.Success)
{
return findViewResult.View;
}
var searchedLocations = getViewResult.SearchedLocations.Concat(findViewResult.SearchedLocations);
var errorMessage = string.Join(
Environment.NewLine,
new[] {$"Unable to find view '{viewName}'. The following locations were searched:"}.Concat(
searchedLocations));
throw new InvalidOperationException(errorMessage);
}
答案 0 :(得分:0)
您尝试过吗:
@await Html.PartialAsync("EmailButton", new EmailButtonViewModel("Confirm Account", "https://google.com"))