It depends which project type are you using. Is your blazor-server will connect directly database or make requests to you existing HttpApi.Host?
Best way to change it to blazor server is creating new project and compare changes like I did in this PR: https://github.com/enisn/abp-blazor-wasm-to-server/pull/1
If your new blazor-server will send requests to HttpApi.Host like exactly same with current webassembly, you can create the project with --tiered parameter.
But you should customize files to watch in .csproj file for including js files according to Microsoft's docs: Customize files list to watch
<ItemGroup>
<!-- extends watching group to include *.js files -->
<Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
</ItemGroup>
Hi @developer_infoline
Have you tried to run your project with dotnet watch run. The watch should watch changes on the rest of the files like css too.
https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-6.0#run-net-core-cli-commands-using-dotnet-watch
dotnet watch refreshes the browser when it detects changes to watched files. To do this, the watch command injects a middleware to the app that modifies HTML responses created by the app. The middleware adds a JavaScript script block to the page that allows dotnet watch to instruct the browser to refresh. Currently, changes to all watched files, including static content such as .html and .css files cause the app to be rebuilt.
Hi @FrancoisLabelle
Your pipeline should restore client libraries too before or after the build and so you can include the libs folder in your docker image too.
I don't understand what you mean by "clean/vanilla server". As I understand you don't dockerize your application and trying to deploy DLLs only? Like IIS deployment. If yes, you can still restore client libraries in your pipeline. It should be a part of your build step. It should be easy to add a new step to the pipeline in each modern DevOps tool.
Remove the .gitignore exclusion and push the libs folder to my source file repository ?
But if you prefer, you can include the libs folder in your git. One of the reasons for removing them is their size. But in a single project, you can choose to keep them in git.
Unfortunately, there is no mention of it in this documentation: https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/additional-scenarios?view=aspnetcore-6.0
We (as ABP Framework) don't implement directly this flow. It's implemented by Microsoft, you may ask them about it. There may be an internal API or something else but I don't think so. Because that component performs the functionality, if you can achieve to remove it, the logout functionality won't be performed at the end.
Hi @trina.thompson
The problem occurs because abp CLI tries to install LeptonX Beta.1 version, but beta.1 is only compatible with ABP 5.2
We're working on this issue. You can add the following dependency into your Web.csproj file manually for now.
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX" Version="1.0.0-beta.2" />```
Hi @lalitChougule
appsettings is not a part of ABP Framework. It's part of Microsoft.Extensions.Configuration namespace. So I'm not sure what is the best way to move configurations to database but there is an example about what you exactly want: https://stackoverflow.com/questions/60330342/can-i-move-configuration-from-appsettings-json-to-database-in-an-asp-net-core-mv
Hi @deepak
We designed permissions to be kept in a Dictionary. Unfortunately dictionaries in C# aren't designed for being able to be sorted. https://stackoverflow.com/a/7521383/7200126
We can consider adding an order to permissions but currently, there is no order in permission groups.
I can show you a workaround until we'll add that feature.
YourProjectNamePermissionDefinitionProvider in .Application.Contracts project and make a manual ordering like below.public override void Define(IPermissionDefinitionContext context)
{
// some other permission additions of your app
// ...
if (context is PermissionDefinitionContext definitionContext)
{
var ordered = definitionContext.Groups.OrderByDescending(...).ToList();
definitionContext.Groups.Clear();
foreach (var item in ordered)
{
definitionContext.Groups.Add(item.Key, item.Value);
}
}
}
Hi again.
For earlier version such as yours, you can add following class into your Domain project and replace & override the QuestionManager with the fixed code block.
I personally don't recommend to set protected or private properties via using reflection but in that case, it can be patched like this.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Forms;
using Volo.Forms.Forms;
using Volo.Forms.Questions;
using Volo.Forms.Questions.ChoosableItems;
namespace YourProjectName;
[ExposeServices(typeof(QuestionManager))]
[Dependency(ReplaceServices = true)]
public class MyQuestionManager : QuestionManager
{
protected IQuestionRepository questionRepository;
public MyQuestionManager(
IQuestionRepository questionRepository,
IFormRepository formRepository,
IGuidGenerator guidGenerator) : base(questionRepository, formRepository, guidGenerator)
{
this.questionRepository = questionRepository;
}
public override async Task<QuestionBase> UpdateAsync(Guid id, string title, int index, bool isRequired, string description, QuestionTypes questionType, bool hasOtherOption, List<(Guid Id, string value, bool isCorrect)> choiceList)
{
var question = await questionRepository.GetAsync(id);
var questionId = question.Id;
var formId = question.FormId;
var creationDate = question.CreationTime;
// This will be removed when EfCore bug is resolved: https://github.com/dotnet/efcore/issues/22016
// Since item with choice collection can't return single object; we can't remove choices over item.
await ClearItemChoicesAsync(question);
question = await questionRepository.GetAsync(id);
await questionRepository.HardDeleteAsync(question, autoSave: true);
var createdQuestion = CreateItemBasedOnType(questionType, questionId);
createdQuestion
.SetFormId(formId)
.SetTitle(title)
.SetIndex(index)
.SetDescription(description);
createdQuestion.SetRequired(isRequired);
createdQuestion.SetOtherOption(hasOtherOption);
if (createdQuestion is IChoosable choosableItem)
{
if (!(question is IChoosable))
{
for (var i = 0; i < choiceList.Count; i++)
{
choosableItem.AddChoice(id: GuidGenerator.Create(), index: i + 1, value: choiceList[i].value, isCorrect: choiceList[i].isCorrect);
}
}
else
{
UpdateIndexesOfChoiceList(choiceList);
choosableItem.AddChoices(choiceList);
}
}
createdQuestion.CreationTime = creationDate;
createdQuestion.LastModificationTime = DateTime.Now;
FixChoicesTenants(createdQuestion);
await UpdateFormLastModificationDateAsync(createdQuestion.FormId);
return await questionRepository.InsertAsync(createdQuestion, true);
}
private void FixChoicesTenants(QuestionBase createdQuestion)
{
if(createdQuestion is Checkbox checkbox)
{
foreach(var choice in checkbox.Choices)
{
SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id);
}
}
if (createdQuestion is ChoiceMultiple choiceMultiple)
{
foreach(var choice in choiceMultiple.Choices)
{
SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id);
}
}
if (createdQuestion is DropdownList dropdownList)
{
foreach(var choice in dropdownList.Choices)
{
SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id);
}
}
}
private void SetProperty<T>(T obj, string propertyName, object value)
{
typeof(T).GetProperty(propertyName)?.SetValue(obj, value);
}
}
In the v5.2.2, you can use -u parameter but somehow -u became a required parameter. We'll fix this in 5.2.3.
But short answer is yes you can use URL parameter in 5.2.2