public async Task Server(String command, String baseUrl, Int64 userId, HttpResponseBase response) { var rm = await RequestModel.CreateFromBaseUrl(_host, Admin, baseUrl); RequestView rw = rm.GetCurrentAction(); String loadProc = rw.LoadProcedure; if (loadProc == null) { throw new RequestModelException("The data model is empty"); } var prms = new ExpandoObject(); prms.Set("UserId", userId); prms.Set("Id", rw.Id); IDataModel model = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, prms); var msi = new ModelScriptInfo() { DataModel = model, Template = rw.template, Path = rw.Path }; var ss = _scripter.GetServerScript(msi); response.ContentType = "text/javascript"; response.Write(ss.Script); }
internal async Task SaveDataObj(Action <ExpandoObject> setParams, ExpandoObject dataToSave, TextWriter writer) { String baseUrl = dataToSave.Get <String>("baseUrl"); if (NormalizeBaseUrl != null) { baseUrl = NormalizeBaseUrl(baseUrl); } ExpandoObject data = dataToSave.Get <ExpandoObject>("data"); var rm = await RequestModel.CreateFromBaseUrl(_host, Admin, baseUrl); RequestView rw = rm.GetCurrentAction(); var prms = new ExpandoObject(); setParams?.Invoke(prms); prms.Append(rw.parameters); CheckUserState(prms); IDataModel model = await _dbContext.SaveModelAsync(rw.CurrentSource, rw.UpdateProcedure, data, prms); IModelHandler handler = rw.GetHookHandler(); if (handler != null) { await handler.AfterSave(data, model.Root); } WriteDataModel(model, writer); }
internal async Task ReloadData(Action <ExpandoObject> setParams, String json, TextWriter writer) { ExpandoObject dataToSave = JsonConvert.DeserializeObject <ExpandoObject>(json, new ExpandoObjectConverter()); String baseUrl = dataToSave.Get <String>("baseUrl"); ExpandoObject loadPrms = new ExpandoObject(); if (baseUrl.Contains("?")) { var parts = baseUrl.Split('?'); baseUrl = parts[0]; // parts[1] contains query parameters var qryParams = HttpUtility.ParseQueryString(parts[1]); loadPrms.Append(CheckPeriod(qryParams), toPascalCase: true); } if (NormalizeBaseUrl != null) { baseUrl = NormalizeBaseUrl(baseUrl); } if (baseUrl == null) { throw new RequestModelException("There are not base url for command 'reload'"); } var rm = await RequestModel.CreateFromBaseUrl(_host, Admin, baseUrl); RequestView rw = rm.GetCurrentAction(); String loadProc = rw.LoadProcedure; if (loadProc == null) { throw new RequestModelException("The data model is empty"); } setParams?.Invoke(loadPrms); loadPrms.Set("Id", rw.Id); loadPrms.Append(rw.parameters); ExpandoObject prms2 = loadPrms; if (rw.indirect) { // for indirect action - @UserId and @Id only prms2 = new ExpandoObject(); setParams?.Invoke(prms2); prms2.Set("Id", rw.Id); } IDataModel model = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, prms2); if (rw.HasMerge) { var mergeModel = await _dbContext.LoadModelAsync(rw.MergeSource, rw.MergeLoadProcedure, prms2); model.Merge(mergeModel); } rw = await LoadIndirect(rw, model, loadPrms); WriteDataModel(model, writer); }
public async Task RenderElementKind(RequestUrlKind kind, String pathInfo, ExpandoObject loadPrms, TextWriter writer) { RequestModel rm = await RequestModel.CreateFromUrl(_host, Admin, kind, pathInfo); RequestView rw = rm.GetCurrentAction(kind); await Render(rw, writer, loadPrms); }
async Task <RequestView> LoadIndirect(RequestView rw, IDataModel innerModel, ExpandoObject loadPrms) { if (!rw.indirect) { return(rw); } if (!String.IsNullOrEmpty(rw.target)) { String targetUrl = innerModel.Root.Resolve(rw.target); if (String.IsNullOrEmpty(rw.targetId)) { throw new RequestModelException("targetId must be specified for indirect action"); } targetUrl += "/" + innerModel.Root.Resolve(rw.targetId); var rm = await RequestModel.CreateFromUrl(_host, Admin, rw.CurrentKind, targetUrl); rw = rm.GetCurrentAction(); String loadProc = rw.LoadProcedure; if (loadProc != null) { loadPrms.Set("Id", rw.Id); var newModel = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, loadPrms); innerModel.Merge(newModel); innerModel.System.Set("__indirectUrl__", rm.BaseUrl); } } else { // simple view/model redirect if (rw.targetModel == null) { throw new RequestModelException("'targetModel' must be specified for indirect action without 'target' property"); } rw.model = innerModel.Root.Resolve(rw.targetModel.model); rw.view = innerModel.Root.Resolve(rw.targetModel.view); rw.viewMobile = innerModel.Root.Resolve(rw.targetModel.viewMobile); rw.schema = innerModel.Root.Resolve(rw.targetModel.schema); if (String.IsNullOrEmpty(rw.schema)) { rw.schema = null; } rw.template = innerModel.Root.Resolve(rw.targetModel.template); if (String.IsNullOrEmpty(rw.template)) { rw.template = null; } String loadProc = rw.LoadProcedure; if (loadProc != null) { loadPrms.Set("Id", rw.Id); var newModel = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, loadPrms); innerModel.Merge(newModel); } } return(rw); }
public async Task RenderElementKind(RequestUrlKind kind, String pathInfo, ExpandoObject loadPrms, TextWriter writer) { RequestModel rm = await RequestModel.CreateFromUrl(_host, kind, pathInfo); RequestView rw = rm.GetCurrentAction(kind); rw.CheckPermissions(_userStateManager?.GetUserPermissions(), Host.IsDebugConfiguration); await Render(rw, writer, loadPrms); }
public async Task RenderModel(String pathInfo, ExpandoObject loadPrms, TextWriter writer) { RequestModel rm = await RequestModel.CreateFromUrl(_host, Admin, RequestUrlKind.Page, pathInfo); RequestView rw = rm.GetCurrentAction(RequestUrlKind.Page); rw.view = NO_VIEW; // no view here await Render(rw, writer, loadPrms); }
internal async Task SaveDataObj(Action <ExpandoObject> setParams, ExpandoObject dataToSave, TextWriter writer) { String baseUrl = dataToSave.Get <String>("baseUrl"); if (NormalizeBaseUrl != null) { baseUrl = NormalizeBaseUrl(baseUrl); } ExpandoObject data = dataToSave.Get <ExpandoObject>("data"); var rm = await RequestModel.CreateFromBaseUrl(_host, baseUrl); RequestView rw = rm.GetCurrentAction(); var prms = new ExpandoObject(); setParams?.Invoke(prms); prms.Append(rw.parameters); CheckUserState(prms); IDataModel model = null; IModelHandler handler = rw.GetHookHandler(); String invokeTarget = rw.GetInvokeTarget(); if (handler != null) { Int64 userId = prms.Get <Int64>("UserId"); var handled = await handler.BeforeSave(userId, data); if (!handled) { model = await _dbContext.SaveModelAsync(rw.CurrentSource, rw.UpdateProcedure, data, prms); await handler.AfterSave(userId, data, model.Root); } } else if (invokeTarget != null) { model = await _dbContext.SaveModelAsync(rw.CurrentSource, rw.UpdateProcedure, data, prms); var clr = new ClrInvoker(); clr.EnableThrow(); clr.Invoke(invokeTarget, prms); // after save } else { model = await _dbContext.SaveModelAsync(rw.CurrentSource, rw.UpdateProcedure, data, prms); } var eh = rw?.events?.afterSave; if (eh != null) { // new model data await _dbContext.SaveModelAsync(eh.CurrentSource(rw), eh.UpdateProcedure(rw), model.Root, prms); } WriteDataModel(model, writer); }
async Task <String> WriteModelScriptModel(RequestView rw, IDataModel model, String rootId) { StringBuilder output = new StringBuilder(); String dataModelText = "null"; String templateText = "{}"; StringBuilder sbRequired = new StringBuilder(); if (model != null) { // write model script String fileTemplateText = null; if (rw.template != null) { fileTemplateText = await _host.ReadTextFile(Admin, rw.Path, rw.template + ".js"); AddRequiredModules(sbRequired, fileTemplateText); templateText = CreateTemplateForWrite(_localizer.Localize(null, fileTemplateText)); } dataModelText = JsonConvert.SerializeObject(model.Root, StandardSerializerSettings); } const String scriptText = @" 'use strict'; window.$currentModule = function() { $(RequiredModules) $(ModelScript) const rawData = $(DataModelText); const template = $(TemplateText); return { dataModel: modelData(template, rawData) }; };"; const String emptyModel = "function modelData() {return null;}"; var text = new StringBuilder(scriptText); text.Replace("$(DataModelText)", dataModelText); text.Replace("$(TemplateText)", _localizer.Localize(null, templateText)); text.Replace("$(RequiredModules)", sbRequired != null ? sbRequired.ToString() : String.Empty); String modelScript = model != null?model.CreateScript(_scripter) : emptyModel; text.Replace("$(ModelScript)", modelScript); output.Append(text); return(output.ToString()); }
protected internal async Task Render(RequestView rwArg, TextWriter writer, ExpandoObject loadPrms, Boolean secondPhase = false) { var dmAndView = await GetDataModelForView(rwArg, loadPrms); IDataModel model = dmAndView.Model; var rw = dmAndView.RequestView; String rootId = "el" + Guid.NewGuid().ToString(); if (_renderer == null) { throw new InvalidOperationException("Service 'IRenderer' not registered"); } var msi = new ModelScriptInfo() { DataModel = model, RootId = rootId, IsDialog = rw.IsDialog, Template = rw.template, Path = rw.Path, BaseUrl = rw.ParentModel.BasePath }; var si = await _scripter.GetModelScript(msi); String modelScript = si.Script; // TODO: use view engines // try xaml String fileName = rw.GetView() + ".xaml"; String basePath = rw.ParentModel.BasePath; String filePath = _host.ApplicationReader.MakeFullPath(rw.Path, fileName); Boolean bRendered = false; if (_host.ApplicationReader.FileExists(filePath)) { // render XAML using (var strWriter = new StringWriter()) { var ri = new RenderInfo() { RootId = rootId, FileName = filePath, FileTitle = fileName, Path = basePath, Writer = strWriter, DataModel = model, Localizer = _localizer, CurrentLocale = null, IsDebugConfiguration = _host.IsDebugConfiguration, SecondPhase = secondPhase }; _renderer.Render(ri); // write markup writer.Write(strWriter.ToString()); bRendered = true; } } else { // try html fileName = rw.GetView() + ".html"; filePath = _host.ApplicationReader.MakeFullPath(rw.Path, fileName); if (_host.ApplicationReader.FileExists(filePath)) { using (_host.Profiler.CurrentRequest.Start(ProfileAction.Render, $"render: {fileName}")) { using (var tr = new StreamReader(filePath)) { String htmlText = await tr.ReadToEndAsync(); htmlText = htmlText.Replace("$(RootId)", rootId); writer.Write(htmlText); bRendered = true; } } } } if (!bRendered) { throw new RequestModelException($"The view '{rw.GetView()}' was not found. The following locations were searched:\n{rw.GetRelativePath(".xaml")}\n{rw.GetRelativePath(".html")}"); } writer.Write(modelScript); }
internal async Task <DataModelAndView> GetDataModelForView(RequestView rw, ExpandoObject loadPrms) { var dmv = new DataModelAndView() { RequestView = rw }; String loadProc = rw.LoadProcedure; IDataModel model = null; if (rw.parameters != null && loadPrms == null) { loadPrms = rw.parameters; } if (loadPrms != null) { loadPrms.AppendIfNotExists(rw.parameters); if (rw.Id != null) { loadPrms.Set("Id", rw.Id); } } if (loadProc != null) { ExpandoObject prms2 = loadPrms; if (rw.indirect) { // for indirect - @TenantId, @UserId and @Id only prms2 = new ExpandoObject(); prms2.Set("Id", rw.Id); if (loadPrms != null) { prms2.Set("UserId", loadPrms.Get <Int64>("UserId")); prms2.Set("TenantId", loadPrms.Get <Int32>("TenantId")); } } model = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, prms2); if (rw.copy) { model.MakeCopy(); } if (!String.IsNullOrEmpty(rw.Id) && !rw.copy) { var me = model.MainElement; if (me.Metadata != null) { var modelId = me.Id ?? String.Empty; if (rw.Id != modelId.ToString()) { throw new RequestModelException($"Element not found. Id={rw.Id}"); } } } } if (rw.indirect) { rw = await LoadIndirect(rw, model, loadPrms); } if (model?.Root != null) { // side effect! rw.view = model.Root.Resolve(rw.view); rw.template = model.Root.Resolve(rw.template); } if (_userStateManager != null && model != null) { Int64 userId = loadPrms.Get <Int64>("UserId"); if (_userStateManager.IsReadOnly(userId)) { model.SetReadOnly(); } } dmv.Model = model; dmv.RequestView = rw; return(dmv); }
internal async Task <DataModelAndView> GetDataModelForView(RequestView rw, ExpandoObject initialParams) { var dmv = new DataModelAndView() { RequestView = rw }; String loadProc = rw.LoadProcedure; // real params = [model.json, id, initial] var realParams = new ExpandoObject(); realParams.Append(rw.parameters); if (rw.Id != null) { realParams.Set("Id", rw.Id); } realParams.Append(initialParams); IDataModel model = null; if (loadProc != null) { ExpandoObject prms2 = realParams; if (rw.indirect) { // for indirect - @TenantId, @UserId and @Id only prms2 = new ExpandoObject(); prms2.Set("Id", rw.Id); if (realParams != null) { prms2.Set("UserId", realParams.Get <Int64>("UserId")); prms2.Set("TenantId", realParams.Get <Int32>("TenantId")); } } model = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, prms2, rw.commandTimeout); if (rw.HasMerge) { var mergeModel = await _dbContext.LoadModelAsync(rw.MergeSource, rw.MergeLoadProcedure, prms2, rw.commandTimeout); model.Merge(mergeModel); } if (rw.copy) { model.MakeCopy(); } if (!String.IsNullOrEmpty(rw.Id) && !rw.copy) { var me = model.MainElement; if (me.Metadata != null) { var modelId = me.Id ?? String.Empty; if (rw.Id != modelId.ToString()) { throw new RequestModelException($"Element not found. Id={rw.Id}"); } } } } if (rw.indirect) { rw = await LoadIndirect(rw, model, realParams); } if (model?.Root != null) { // side effect! rw.view = model.Root.Resolve(rw.view); rw.viewMobile = model.Root.Resolve(rw.viewMobile); rw.template = model.Root.Resolve(rw.template); rw.checkTypes = model.Root.Resolve(rw.checkTypes); } if (_userStateManager != null && model != null) { Int64 userId = realParams.Get <Int64>("UserId"); if (_userStateManager.IsReadOnly(userId)) { model.SetReadOnly(); } } dmv.Model = model; dmv.RequestView = rw; return(dmv); }
async Task <String> WriteModelScript(RequestView rw, IDataModel model, String rootId) { StringBuilder output = new StringBuilder(); String dataModelText = "{}"; String templateText = "{}"; StringBuilder sbRequired = new StringBuilder(); // write model script String fileTemplateText = null; if (rw.template != null) { fileTemplateText = await _host.ReadTextFile(Admin, rw.Path, rw.template + ".js"); AddRequiredModules(sbRequired, fileTemplateText); templateText = CreateTemplateForWrite(_localizer.Localize(null, fileTemplateText)); } if (model != null) { dataModelText = JsonConvert.SerializeObject(model.Root, StandardSerializerSettings); } const String scriptHeader = @" <script type=""text/javascript""> 'use strict'; $(RequiredModules) (function() { const DataModelController = component('baseController'); const utils = require('std:utils'); const uPeriod = require('std:period'); const rawData = $(DataModelText); const template = $(TemplateText); "; const String scriptFooter = @" const vm = new DataModelController({ el:'#$(RootId)', props: { inDialog: {type: Boolean, default: $(IsDialog)}, pageTitle: {type: String} }, data: modelData(template, rawData), computed: { utils() { return utils; }, period() { return uPeriod; } }, }); vm.$data._host_ = { $viewModel: vm }; vm.__doInit__(); })(); </script> "; var header = new StringBuilder(scriptHeader); header.Replace("$(RootId)", rootId); header.Replace("$(DataModelText)", dataModelText); header.Replace("$(TemplateText)", _localizer.Localize(null, templateText)); header.Replace("$(RequiredModules)", sbRequired != null ? sbRequired.ToString() : String.Empty); output.Append(header); if (model != null) { output.Append(model.CreateScript(_scripter)); } else { output.Append(_scripter.CreateEmptyStript()); } var footer = new StringBuilder(scriptFooter); footer.Replace("$(RootId)", rootId); footer.Replace("$(IsDialog)", rw.IsDialog.ToString().ToLowerInvariant()); output.Append(footer); return(output.ToString()); }
protected async Task Render(RequestView rw, TextWriter writer, ExpandoObject loadPrms) { String loadProc = rw.LoadProcedure; IDataModel model = null; if (rw.parameters != null && loadPrms == null) { loadPrms = rw.parameters; } if (loadPrms != null) { loadPrms.Set("Id", rw.Id); loadPrms.AppendAndReplace(rw.parameters); } if (loadProc != null) { ExpandoObject prms2 = loadPrms; if (rw.indirect) { // for indirect - @TenantId, @UserId and @Id only prms2 = new ExpandoObject(); prms2.Set("Id", rw.Id); if (loadPrms != null) { prms2.Set("UserId", loadPrms.Get <Int64>("UserId")); prms2.Set("TenantId", loadPrms.Get <Int32>("TenantId")); } } model = await _dbContext.LoadModelAsync(rw.CurrentSource, loadProc, prms2); if (!String.IsNullOrEmpty(rw.Id)) { var modelId = model.FirstElementId ?? String.Empty; if (rw.Id != modelId.ToString()) { throw new RequestModelException($"Element not found. Id={rw.Id}"); } } } if (rw.indirect) { rw = await LoadIndirect(rw, model, loadPrms); } if (_userStateManager != null && model != null) { Int64 userId = loadPrms.Get <Int64>("UserId"); if (_userStateManager.IsReadOnly(userId)) { model.SetReadOnly(); } } String rootId = "el" + Guid.NewGuid().ToString(); String modelScript = null; String viewName = rw.GetView(); if (viewName == NO_VIEW) { modelScript = await WriteModelScriptModel(rw, model, rootId); writer.Write(modelScript); return; } if (_renderer == null) { throw new InvalidOperationException("Service 'IRenderer' not registered"); } modelScript = await WriteModelScript(rw, model, rootId); // TODO: use view engines // try xaml String fileName = rw.GetView() + ".xaml"; String filePath = _host.MakeFullPath(Admin, rw.Path, fileName); Boolean bRendered = false; if (System.IO.File.Exists(filePath)) { // render XAML if (System.IO.File.Exists(filePath)) { using (var strWriter = new StringWriter()) { var ri = new RenderInfo() { RootId = rootId, FileName = filePath, FileTitle = fileName, Writer = strWriter, DataModel = model, Localizer = _localizer, CurrentLocale = null, IsDebugConfiguration = _host.IsDebugConfiguration }; _renderer.Render(ri); // write markup writer.Write(strWriter.ToString()); bRendered = true; } } } else { // try html fileName = rw.GetView() + ".html"; filePath = _host.MakeFullPath(Admin, rw.Path, fileName); if (System.IO.File.Exists(filePath)) { using (_host.Profiler.CurrentRequest.Start(ProfileAction.Render, $"render: {fileName}")) { using (var tr = new StreamReader(filePath)) { String htmlText = await tr.ReadToEndAsync(); htmlText = htmlText.Replace("$(RootId)", rootId); writer.Write(htmlText); bRendered = true; } } } } if (!bRendered) { throw new RequestModelException($"The view '{rw.GetView()}' was not found. The following locations were searched:\n{rw.GetRelativePath(".xaml")}\n{rw.GetRelativePath(".html")}"); } writer.Write(modelScript); }