public async Task <string> RenderViewToStringAsync <T>(string pageName, T model) { var actionContext = new ActionContext( _httpContext.HttpContext, _httpContext.HttpContext.GetRouteData(), _actionContext.ActionContext.ActionDescriptor ); using (var sw = new StringWriter()) { var result = _razorViewEngine.FindPage(actionContext, 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( actionContext, view, new ViewDataDictionary <T>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }, new TempDataDictionary( _httpContext.HttpContext, _tempDataProvider ), sw, new HtmlHelperOptions() ); var page = (result.Page); page.ViewContext = viewContext; _activator.Activate(page, viewContext); await page.ExecuteAsync(); return(sw.ToString()); } }
private IRazorPage GetLayoutPage(ViewContext context, string executingFilePath, string layoutPath) { var layoutPageResult = _viewEngine.GetPage(executingFilePath, layoutPath); var originalLocations = layoutPageResult.SearchedLocations; if (layoutPageResult.Page == null) { layoutPageResult = _viewEngine.FindPage(context, layoutPath); } if (layoutPageResult.Page == null) { var locations = string.Empty; if (originalLocations.Any()) { locations = Environment.NewLine + string.Join(Environment.NewLine, originalLocations); } if (layoutPageResult.SearchedLocations.Any()) { locations += Environment.NewLine + string.Join(Environment.NewLine, layoutPageResult.SearchedLocations); } throw new InvalidOperationException(Resources.FormatLayoutCannotBeLocated(layoutPath, locations)); } var layoutPage = layoutPageResult.Page; return(layoutPage); }
public async Task <string> RenderPageAsync <T>(T model, string path, string area = null) { var actionContext = CreateActionContext(path, area ?? string.Empty); var page = _engine.FindPage(actionContext, path).Page as Page; if (page == null) { throw new ArgumentException($"Unable to find page {path}"); } var view = CreateView(page); using (var writer = new StringWriter()) { var viewContext = CreateViewContext(actionContext, view, model, writer); page.PageContext = new PageContext { ViewData = viewContext.ViewData }; page.ViewContext = viewContext; _activator.Activate(page, viewContext); await page.ExecuteAsync(); var rendered = writer.ToString(); return(rendered); } }
public string GetLayoutName(ViewContext viewContext) { ISiteSettings site = siteResolver.Resolve(); if (site == null) { return(options.DefaultLayout); } string layout = options.DefaultLayout.Replace(".cshtml", string.Empty); // "Default_Layout" // resolve tenant specific layout file name if (options.SelectionMode == LayoutSelectionMode.Convention) { // with this mode layouts are not shown in a dropdown list in site settings // so the layout cannot be changed from the UI // use a convention like Site1Layout.cshtml Site2Layout.cshtml // based on siteid layout = string.Format(CultureInfo.InvariantCulture, options.ConventionFormat, site.SiteId.ToInvariantString()); } else { // LayoutSelectionMode.Browsing -- this is the default // in this mode a dropdown list of available layouts is shown // and the layout can be chosen from the UI // the list is filtered per tenant using file naming conventions // where the SiteID is part of the filename format // ie you could name files like this: // Site1_dark_Layout.cshtml // Site1_light_Layout.cshtml // Site2_supercool_Layout.cshtml // Site2_autumn_Layout.cshtml // ... if (site.Layout.Length > 0) { layout = site.Layout.Replace(".cshtml", string.Empty); } } // in all cases we need to determine of the layout file exists // and if not log something and fallback to a known layout file var layoutPageResult = viewEngine.FindPage(viewContext, layout); if (layoutPageResult.Page == null) { log.LogError("could not find the layout " + layout); return(options.DefaultLayout.Replace(".cshtml", string.Empty)); } log.LogDebug("using the layout " + layout); return(layout); }
public string GetLayoutName(ViewContext viewContext) { ISiteSettings site = siteResolver.Resolve(); if (site == null) { return(options.DefaultLayout); } string layout = options.DefaultLayout; //"_Layout" // resolve tenant specific layout file name if (options.SelectionMode == LayoutSelectionMode.Convention) // this is the default for now { // we could use a convention like Site1Layout.cshtml Site2Layout.cshtml // based on siteid layout = string.Format(CultureInfo.InvariantCulture, options.ConventionFormat, site.SiteId.ToInvariantString()); } else { // we could store a layout name in ISiteSettings.Skin // in that case we would need a way to browse layout files from the UI // and tricky logic or conventions to filter to only layout files so no other views can be chosen // then if we do that would we need a way to make each tenant not be able to select // a layout that belongs to another tenant? // generally I think of multi-tenant for multiple sites owned by the same customer // so in that case it is not a big issue for one tenant to see the other tenant layouts // need a way to enumerate layout views in the file system to populate a dropdown // currently there is no ui for selecting a layout so you would have to set it in the db // in mp_Sites.Skin field if (site.Skin.Length > 0) { layout = site.Skin.Replace(".cshtml", string.Empty); } } // in all cases we need to determine of the layout file exists // and if not log something and fallback to a known layout file var layoutPageResult = viewEngine.FindPage(viewContext, layout); if (layoutPageResult.Page == null) { log.LogError("could not find the layout " + layout); return(options.DefaultLayout); } else { //log.LogInformation("found the layout " + layout); return(layout); } }
public static async Task <string> RenderViewAsync(this PageModel pageModel, string pageName) { var actionContext = new ActionContext( pageModel.HttpContext, pageModel.RouteData, pageModel.PageContext.ActionDescriptor ); using (var sw = new StringWriter()) { IRazorViewEngine _razorViewEngine = pageModel.HttpContext.RequestServices.GetService(typeof(IRazorViewEngine)) as IRazorViewEngine; IRazorPageActivator _activator = pageModel.HttpContext.RequestServices.GetService(typeof(IRazorPageActivator)) as IRazorPageActivator; var result = _razorViewEngine.FindPage(actionContext, pageName); if (result.Page == null) { throw new ArgumentNullException($"The page {pageName} cannot be found."); } var page = result.Page; var view = new RazorView(_razorViewEngine, _activator, new List <IRazorPage>(), page, HtmlEncoder.Default, new DiagnosticListener("ViewRenderService")); var viewContext = new ViewContext( actionContext, view, pageModel.ViewData, pageModel.TempData, sw, new HtmlHelperOptions() ); var pageNormal = ((Page)result.Page); pageNormal.PageContext = pageModel.PageContext; pageNormal.ViewContext = viewContext; _activator.Activate(pageNormal, viewContext); await page.ExecuteAsync(); return(sw.ToString()); } }
public string Render(HttpContext context, string layout, string viewName, object model = null, Dictionary <string, object> viewData = null) { ActionContext actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor()); using (var sw = new StringWriter()) { RazorPageResult viewResult = _razorViewEngine.FindPage(actionContext, viewName); viewResult.Page.Layout = layout; if (viewResult.Page == null) { throw new Exception($"{viewName} does not match any available view"); } var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); if (model != null) { viewDictionary.Model = model; } if (viewData != null) { foreach (var item in viewData) { viewDictionary[item.Key] = item.Value; } } var opts = new HtmlHelperOptions(); var viewContext = new ViewContext(); //var viewContext = new ViewContext( // actionContext, // null, // viewDictionary, // new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), // sw, // opts //); viewResult.Page.ViewContext = new ViewContext(); viewResult.Page.ViewContext.View.RenderAsync(viewContext); Task.WaitAll(viewResult.Page.ExecuteAsync()); viewResult.Page.ViewContext.ViewData = viewDictionary; viewResult.Page.ViewContext.Writer = sw; Task.WaitAll(viewResult.Page.ViewContext.View.RenderAsync(viewContext)); return(sw.ToString()); } }
public RazorPageResult FindPage(ActionContext context, string pageName) { _locker.EnterReadLock(); try { return(_current.FindPage(context, pageName)); } finally { _locker.ExitReadLock(); } }
private IRazorPage GetLayoutPage(ViewContext context, string layoutPath) { var layoutPageResult = _viewEngine.FindPage(context, layoutPath); if (layoutPageResult.Page == null) { throw new InvalidOperationException("Cannot locate layout " + layoutPath); } var layoutPage = layoutPageResult.Page; return(layoutPage); }
private IRazorPage GetLayoutPage(ViewContext context, string layoutPath) { var layoutPageResult = _viewEngine.FindPage(context, layoutPath); if (layoutPageResult.Page == null) { var locations = Environment.NewLine + string.Join(Environment.NewLine, layoutPageResult.SearchedLocations); throw new InvalidOperationException(Resources.FormatLayoutCannotBeLocated(layoutPath, locations)); } var layoutPage = layoutPageResult.Page; return(layoutPage); }
/// <summary> /// 查找Razor页面 /// </summary> /// <param name="razorViewEngine">Razor视图引擎</param> /// <param name="actionContext">操作上下文</param> /// <param name="pageName">页面名称。执行文件路径:/Pages/Components/Forms/Form.cshtml</param> private IRazorPage FindPage(IRazorViewEngine razorViewEngine, ActionContext actionContext, string pageName) { var getPageResult = razorViewEngine.GetPage(null, pageName); if (getPageResult.Page != null) { return(getPageResult.Page); } var findPageResult = razorViewEngine.FindPage(actionContext, pageName); if (findPageResult.Page != null) { return(findPageResult.Page); } throw new ArgumentNullException($"未找到视图: {pageName}"); }
private async Task <string> RenderPageAsString(ActionContext actionContext) { using var sw = new StringWriter(); var pageResult = _razorViewEngine.FindPage(actionContext, _razorPageName);; if (pageResult.Page == null) { throw new ArgumentNullException($"The page {_razorPageName} cannot be found."); } var viewContext = GetViewContext(actionContext, pageResult.Page, sw); var page = (Page)pageResult.Page; page.PageContext = PageModel.PageContext; page.ViewContext = viewContext; _activator.Activate(page, viewContext); await page.ExecuteAsync(); return(sw.ToString()); }
public async Task <string> RenderToStringAsync <T>(string pageName, T model) where T : PageModel { var actionContext = new ActionContext(httpContext.HttpContext, httpContext.HttpContext.GetRouteData(), this.actionContextAccessor.ActionContext.ActionDescriptor); await using var writer = new StringWriter(); var result = razorViewEngine.FindPage(actionContext, pageName); if (result.Page == null) { throw new ArgumentNullException($"The page {pageName} cannot be found."); } using var listener = new DiagnosticListener("ViewRenderService"); var view = new RazorView(razorViewEngine, activator, new List <IRazorPage>(), result.Page, HtmlEncoder.Default, listener); var viewDataDictionary = new ViewDataDictionary <T>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }; var viewContext = new ViewContext( actionContext, view, viewDataDictionary, new TempDataDictionary(httpContext.HttpContext, tempDataProvider), writer, new HtmlHelperOptions()); var page = (Page)result.Page; page.PageContext = new PageContext { ViewData = viewContext.ViewData }; page.ViewContext = viewContext; activator.Activate(page, viewContext); await page.ExecuteAsync().ConfigureAwait(false); return(writer.ToString()); }
private IRazorPage FindPage(ActionContext actionContext, string partialName) { var getPartialResult = _viewEngine.GetPage(null, partialName); if (getPartialResult.Page != null) { return(getPartialResult.Page); } var findPartialResult = _viewEngine.FindPage(actionContext, partialName); if (findPartialResult.Page != null) { return(findPartialResult.Page); } var searchedLocations = getPartialResult.SearchedLocations.Concat(findPartialResult.SearchedLocations); var errorMessage = string.Join( Environment.NewLine, new[] { $"Unable to find partial '{partialName}'. The following locations were searched:" }.Concat(searchedLocations));; throw new InvalidOperationException(errorMessage); }