/// <summary> /// 将视图写入文件 /// </summary> /// <param name="info">路由信息</param> /// <returns></returns> public async Task WriteViewToFileAsync(RouteInformation info) { try { var html = await RenderToStringAsync(info); if (string.IsNullOrWhiteSpace(html)) { return; } var path = Util.Helpers.Common.GetPhysicalPath(string.IsNullOrWhiteSpace(info.FilePath) ? GetPath(info) : info.FilePath); var directory = System.IO.Path.GetDirectoryName(path); if (string.IsNullOrWhiteSpace(directory)) { return; } if (Directory.Exists(directory) == false) { Directory.CreateDirectory(directory); } File.WriteAllText(path, html); } catch (Exception ex) { ex.Log(Log.GetLog().Caption("生成html静态文件失败")); } }
/// <summary> /// 获取Html默认生成路径 /// </summary> /// <param name="info">路由信息</param> /// <returns></returns> protected virtual string GetPath(RouteInformation info) { if (!info.IsPageRoute) { var area = info.AreaName.SafeString(); var controller = info.ControllerName.SafeString(); var action = info.ActionName.SafeString(); var path = info.TemplatePath.Replace("{area}", area).Replace("{controller}", controller).Replace("{action}", action); return(path.ToLower()); } if (!string.IsNullOrWhiteSpace(info.FilePath)) { return(info.FilePath.ToLower()); } var paths = info.Path.TrimStart('/').Split('/'); if (paths.Length >= 3) { return(info.TemplatePath.Replace("{area}", paths[0]) .Replace("{controller}", paths[1]) .Replace("{action}", JoinActionUrl(paths))); } return(string.Empty); }
/// <summary> /// 获取Html默认生成路径 /// </summary> /// <param name="info">路由信息</param> /// <returns></returns> protected virtual string GetPath(RouteInformation info) { var area = info.AreaName.SafeString(); var controller = info.ControllerName.SafeString(); var action = info.ActionName.SafeString(); var path = info.TemplatePath.Replace("{area}", area).Replace("{controller}", controller).Replace("{action}", action); return(path.ToLower()); }
/// <summary> /// 获取所有路由信息 /// </summary> public IEnumerable <RouteInformation> GetAllRouteInformations() { List <RouteInformation> list = new List <RouteInformation>(); var actionDescriptors = this._actionDescriptorCollectionProvider.ActionDescriptors.Items; foreach (var actionDescriptor in actionDescriptors) { RouteInformation info = new RouteInformation(); if (actionDescriptor.RouteValues.ContainsKey("area")) { info.AreaName = actionDescriptor.RouteValues["area"]; } // Razor页面路径以及调用 if (actionDescriptor is PageActionDescriptor pageActionDescriptor) { var compiledPage = _pageLoader.Load(pageActionDescriptor); info.Path = pageActionDescriptor.ViewEnginePath; info.Invocation = pageActionDescriptor.RelativePath; SetHtmlInfo(info, compiledPage); if (!list.Exists(x => x.Invocation == info.Invocation)) { list.Add(info); } continue; } // 路由属性路径 if (actionDescriptor.AttributeRouteInfo != null) { info.Path = $"/{actionDescriptor.AttributeRouteInfo.Template}"; } // Controller/Action 的路径以及调用 if (actionDescriptor is ControllerActionDescriptor controllerActionDescriptor) { if (info.Path.IsEmpty()) { info.Path = $"/{controllerActionDescriptor.ControllerName}/{controllerActionDescriptor.ActionName}"; } SetHtmlInfo(info, controllerActionDescriptor); info.ControllerName = controllerActionDescriptor.ControllerName; info.ActionName = controllerActionDescriptor.ActionName; info.Invocation = $"{controllerActionDescriptor.ControllerName}Controller.{controllerActionDescriptor.ActionName}"; } info.Invocation += $"({actionDescriptor.DisplayName})"; list.Add(info); } return(list); }
/// <summary> /// 设置Html信息 /// </summary> /// <param name="routeInformation">路由信息</param> /// <param name="controllerActionDescriptor">控制器</param> private void SetHtmlInfo(RouteInformation routeInformation, ControllerActionDescriptor controllerActionDescriptor) { var htmlAttribute = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute <HtmlAttribute>() ?? controllerActionDescriptor.MethodInfo.GetCustomAttribute <HtmlAttribute>(); if (htmlAttribute == null) { return; } routeInformation.FilePath = htmlAttribute.Path; routeInformation.TemplatePath = htmlAttribute.Template; routeInformation.IsPartialView = htmlAttribute.IsPartialView; routeInformation.ViewName = htmlAttribute.ViewName; }
/// <summary> /// 设置Html信息 /// </summary> /// <param name="routeInformation">路由信息</param> /// <param name="compiledPageActionDescriptor">编译后的页面</param> private void SetHtmlInfo(RouteInformation routeInformation, CompiledPageActionDescriptor compiledPageActionDescriptor) { routeInformation.IsPageRoute = true; var htmlAttribute = compiledPageActionDescriptor.PageTypeInfo.GetCustomAttribute <HtmlAttribute>() ?? compiledPageActionDescriptor.DeclaredModelTypeInfo.GetCustomAttribute <HtmlAttribute>(); if (htmlAttribute == null) { return; } routeInformation.FilePath = htmlAttribute.Path; routeInformation.TemplatePath = htmlAttribute.Template; routeInformation.IsPartialView = htmlAttribute.IsPartialView; routeInformation.ViewName = htmlAttribute.ViewName; }
/// <summary> /// 获取路由数据 /// </summary> /// <param name="info">路由信息</param> /// <returns></returns> protected virtual RouteData GetRouteData(RouteInformation info) { var routeData = new RouteData(); if (!info.AreaName.IsEmpty()) { routeData.Values.Add("area", info.AreaName); } if (!info.ControllerName.IsEmpty()) { routeData.Values.Add("controller", info.ControllerName); } if (!info.ActionName.IsEmpty()) { routeData.Values.Add("action", info.ActionName); } return(routeData); }
/// <summary> /// 渲染视图为字符串 /// </summary> /// <param name="info">路由信息</param> /// <returns></returns> public async Task <string> RenderToStringAsync(RouteInformation info) { var razorViewEngine = Ioc.Create <IRazorViewEngine>(); var tempDataProvider = Ioc.Create <ITempDataProvider>(); var serviceProvider = Ioc.Create <IServiceProvider>(); var routeData = new RouteData(); if (!info.AreaName.IsEmpty()) { routeData.Values.Add("area", info.AreaName); } if (!info.ControllerName.IsEmpty()) { routeData.Values.Add("controller", info.ControllerName); } if (!info.ActionName.IsEmpty()) { routeData.Values.Add("action", info.ActionName); } var httpContext = new DefaultHttpContext { RequestServices = serviceProvider }; var actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); var viewResult = razorViewEngine.FindView(actionContext, info.ActionName, true); if (!viewResult.Success) { throw new InvalidOperationException($"找不到视图模板 {info.ActionName}"); } using (var stringWriter = new StringWriter()) { var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); var viewContext = new ViewContext(actionContext, viewResult.View, viewDictionary, new TempDataDictionary(actionContext.HttpContext, tempDataProvider), stringWriter, new HtmlHelperOptions()); await viewResult.View.RenderAsync(viewContext); return(stringWriter.ToString()); } }
/// <summary> /// 渲染Action视图为字符串 /// </summary> /// <param name="info">路由信息</param> /// <returns></returns> private async Task <string> RenderActionViewToStringAsync(RouteInformation info) { var razorViewEngine = Ioc.Create <IRazorViewEngine>(); var tempDataProvider = Ioc.Create <ITempDataProvider>(); var serviceProvider = Ioc.Create <IServiceProvider>(); var httpContext = new DefaultHttpContext { RequestServices = serviceProvider }; var actionContext = new ActionContext(httpContext, GetRouteData(info), new ActionDescriptor()); var viewResult = GetView(razorViewEngine, actionContext, info); if (!viewResult.Success) { throw new InvalidOperationException($"找不到视图模板 {info.ActionName}"); } using (var stringWriter = new StringWriter()) { var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); var viewContext = new ViewContext(actionContext, viewResult.View, viewDictionary, new TempDataDictionary(actionContext.HttpContext, tempDataProvider), stringWriter, new HtmlHelperOptions()); await viewResult.View.RenderAsync(viewContext); return(stringWriter.ToString()); } }
/// <summary> /// 获取Razor视图 /// </summary> /// <param name="razorViewEngine">Razor视图引擎</param> /// <param name="actionContext">操作上下文</param> /// <param name="info">路由信息</param> /// <returns></returns> protected virtual ViewEngineResult GetView(IRazorViewEngine razorViewEngine, ActionContext actionContext, RouteInformation info) { return(razorViewEngine.FindView(actionContext, info.ViewName.IsEmpty() ? info.ActionName : info.ViewName, !info.IsPartialView)); }
/// <summary> /// 获取Razor视图 /// </summary> /// <param name="engine">复合视图引擎</param> /// <param name="info">路由信息</param> /// <returns></returns> protected virtual ViewEngineResult GetView(ICompositeViewEngine engine, RouteInformation info) { return(engine.GetView("~/", $"~{info.Invocation}", !info.IsPartialView)); }
/// <summary> /// 获取所有路由信息 /// </summary> /// <returns></returns> public IEnumerable <RouteInformation> GetAllRouteInformations() { List <RouteInformation> list = new List <RouteInformation>(); var actionDescriptors = this._actionDescriptorCollectionProvider.ActionDescriptors.Items; foreach (var actionDescriptor in actionDescriptors) { RouteInformation info = new RouteInformation(); if (actionDescriptor.RouteValues.ContainsKey("area")) { info.AreaName = actionDescriptor.RouteValues["area"]; } // Razor页面路径以及调用 if (actionDescriptor is PageActionDescriptor pageActionDescriptor) { info.Path = pageActionDescriptor.ViewEnginePath; info.Invocation = pageActionDescriptor.RelativePath; } // 路由属性路径 if (actionDescriptor.AttributeRouteInfo != null) { info.Path = $"/{actionDescriptor.AttributeRouteInfo.Template}"; } // Controller/Action 的路径以及调用 if (actionDescriptor is ControllerActionDescriptor controllerActionDescriptor) { if (info.Path.IsEmpty()) { info.Path = $"/{controllerActionDescriptor.ControllerName}/{controllerActionDescriptor.ActionName}"; } var controllerHtmlAttribute = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute <HtmlAttribute>(); if (controllerHtmlAttribute != null) { info.FilePath = controllerHtmlAttribute.Path; info.TemplatePath = controllerHtmlAttribute.Template; } var htmlAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttribute <HtmlAttribute>(); if (htmlAttribute != null) { info.FilePath = htmlAttribute.Path; info.TemplatePath = htmlAttribute.Template; } info.ControllerName = controllerActionDescriptor.ControllerName; info.ActionName = controllerActionDescriptor.ActionName; info.Invocation = $"{controllerActionDescriptor.ControllerName}Controller.{controllerActionDescriptor.ActionName}"; } info.Invocation += $"({actionDescriptor.DisplayName})"; list.Add(info); } return(list); }