/// <summary> /// Load specific component by name /// </summary> internal ComponentInfo Load(IPrincipal user, IServiceProvider service, string name) { if (_components.TryGetValue(name, out var c)) { if (c.IsAutenticated && user.Identity.IsAuthenticated == false) { return(ComponentInfo.Error(name, new HttpException(401))); } if (c.Roles.Length > 0 && c.Roles.Any(x => user.IsInRole(x)) == false) { return(ComponentInfo.Error(name, new HttpException(403))); } return(c); } else if (_discovers.TryGetValue(name, out var d)) { var loader = new ComponentLoader(service, _compilers); c = loader.Load(d); _components[c.Name] = c; if (c.IsAutenticated && user.Identity.IsAuthenticated == false) { return(ComponentInfo.Error(name, new HttpException(401))); } if (c.Roles.Length > 0 && c.Roles.Any(x => user.IsInRole(x)) == false) { return(ComponentInfo.Error(name, new HttpException(403))); } return(c); } else { return(ComponentInfo.Error(name, new Exception($"Component {name} not exists"))); } }
internal ComponentRender(ComponentInfo component, IPrincipal user) { _component = component; _user = user; }
internal ComponentUpdate(ComponentInfo component, IPrincipal user) { _component = component; _user = user; }
public ComponentInfo Load(Assembly assembly, string resourceName, StringBuilder globalScripts) { // try read file from local disk (for hot reload) var localFile = Path.Combine(_root + @"\..\", assembly.GetName().Name + resourceName.Substring(assembly.GetName().Name.Length, resourceName.Length - assembly.GetName().Name.Length - 4).Replace(".", "\\")) + ".vue"; var content = File.Exists(localFile) ? File.ReadAllText(localFile) : new StreamReader(assembly.GetManifestResourceStream(resourceName)).ReadToEnd(); var html = new HtmlFile(content, globalScripts); var name = html.GetDirective("name") ?? Path.GetFileNameWithoutExtension(localFile); var component = new ComponentInfo(name); if (html.Directives.TryGetValue("viewmodel", out var viewModel)) { component.ViewModelType = assembly.GetType(viewModel, true); } else { // try guess viewModel based on resource name component.ViewModelType = assembly.GetType(resourceName.Substring(0, resourceName.Length - 4)) ?? typeof(ViewModel); } component.IsAsync = html.Directives.ContainsKey("async"); if (html.Directives.TryGetValue("page", out var route)) { component.IsPage = true; component.Route = route; } component.Template = html.Template.ToString().Trim(); component.Styles = html.Styles.ToString(); component.Scripts = html.Scripts.ToString() + this.GetScriptAttr(component.ViewModelType); component.Mixins = html.Mixins; using (var instance = (ViewModel)ActivatorUtilities.CreateInstance(_service, component.ViewModelType)) { component.JsonData = this.GetJsonData(instance); component.Methods = this.GetMethods(component.ViewModelType).ToDictionary(x => x.Method.Name, x => x, StringComparer.OrdinalIgnoreCase); component.Props = this.GetField <PropAttribute>(component.ViewModelType, instance); component.RouteParams = this.GetField <RouteParamAttribute>(component.ViewModelType, instance); component.QueryString = this.GetField <QueryStringAttribute>(component.ViewModelType, instance); component.LocalStorage = component.ViewModelType .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(x => x.GetCustomAttribute <LocalStorageAttribute>() != null) .ToDictionary(x => x.Name, x => x.GetCustomAttribute <LocalStorageAttribute>().Key ?? x.Name.ToCamelCase(), StringComparer.OrdinalIgnoreCase); } component.InheritAttrs = !component.Template.Contains("v-bind=\"$attrs\""); component.IsAuthenticated = component.ViewModelType.GetCustomAttribute <AutorizeAttribute>() != null; if (component.IsAuthenticated) { component.Roles = component.ViewModelType.GetCustomAttribute <AutorizeAttribute>().Roles; } return(component); }
public void RenderComponent(ComponentInfo component) { _writer.Append($"{{\n"); // add vpath to options _writer.Append($" name: '{component.Name}',\n"); if (component.InheritAttrs == false) { _writer.Append($" inheritAttrs: false,\n"); } if (component.Props.Count > 0) { _writer.Append($" props: {{\n"); foreach (var prop in component.Props) { var name = prop.Key.ToCamelCase(); var value = JsonConvert.SerializeObject(prop.Value); var last = prop.Key == component.Props.Last().Key ? "" : ","; _writer.Append($" {name}: {{ default: {value} }}{last}\n"); } _writer.Append($" }},\n"); } // append template string _writer.Append($" template: `{component.Template.EncodeJavascript('`')}`,\n"); _writer.Append($" data: function() {{\n"); _writer.Append($" return {JsonConvert.SerializeObject(component.JsonData)};\n"); _writer.Append($" }},\n"); // render methods if (component.Methods.Count > 0) { _writer.Append($" methods: {{\n"); foreach (var m in component.Methods) { var name = m.Value.Method.Name.ToCamelCase(); var last = m.Key == component.Methods.Last().Key ? "" : ","; _writer.Append($" {name}: function(...args) {{\n"); _writer.Append($" return this.$server('{name}', ...args);\n"); _writer.Append($" }}{last}\n"); // method } _writer.Append(" },\n"); // methods } // render watchs var watch = component.Methods.Where(x => x.Value.Watch != null).ToArray(); if (watch.Length > 0 || component.LocalStorage.Count > 0) { _writer.Append($" watch: {{\n"); foreach (var w in watch) { var name = w.Value.Watch.ToCamelCase(); var method = w.Value.Method.Name.ToCamelCase(); _writer.Append($" {name}: function(v, o) {{\n"); _writer.Append($" this.{method}(v, o);\n"); _writer.Append($" }},\n"); } foreach (var w in component.LocalStorage) { var name = w.Key.ToCamelCase(); var key = w.Value; _writer.Append($" {name}: function(v, o) {{\n"); _writer.Append($" if(v === null || v === undefined) localStorage.removeItem('{key}'); else localStorage.setItem('{key}', v);\n"); _writer.Append($" }},\n"); } _writer.Append(" },\n"); } // render mixin script if (component.Mixins.Count > 0) { _writer.Append($" mixins: [\n"); foreach (var s in component.Mixins) { var last = s == component.Mixins.Last() ? "" : ","; _writer.Append($"(function() {{\n"); _writer.Append(s); _writer.Append($"}})() || {{}}{last}\n"); } _writer.Append(" ],\n"); } // register initial scripts and/or hood OnCreated server call if (component.CreatedHook || !string.IsNullOrEmpty(component.Scripts) || component.QueryString.Count > 0 || component.RouteParams.Count > 0 || component.LocalStorage.Count > 0) { _writer.Append($" created: function() {{\n"); foreach (var rp in component.RouteParams) { var name = rp.Key.ToCamelCase(); _writer.Append($" if (this.$route.params.{name} !== undefined) this.{name} = this.$route.params.{name};\n"); } foreach (var qs in component.QueryString) { var name = qs.Key.ToCamelCase(); _writer.Append($" if (this.$route.query.{name} !== undefined) this.{name} = this.$route.query.{name};\n"); } foreach (var ls in component.LocalStorage) { var name = ls.Key.ToCamelCase(); var key = ls.Value; _writer.Append($" if (localStorage.getItem('{key}') !== null) this.{name} = localStorage.getItem('{key}');\n"); } if (!string.IsNullOrEmpty(component.Scripts)) { _writer.Append(component.Scripts); } if (component.CreatedHook) { _writer.Append($" this.onCreated();\n"); } _writer.Append($" }},\n"); } _writer.Append(" mounted: function() { this.$emit('mounted'); }\n"); _writer.Append($"}}"); }