Elsa workflow versioning - elsa-workflows

I have created a simple workflow, first time publish it is working fine when I change something and publish then it is throwing an exception: "The call is ambiguous and matches multiple workflows". How to handle this?

I was experiencing the same issue. There appears to be an issue in Elsa where the "IsLatest" flag on the WorkflowDefinition table doesn't get turned off for the prior version of that workflow. There is some documentation around the issue here:
https://gitmemory.com/issue/elsa-workflows/elsa-core/1293/886656398
In my case, I fixed this by manually setting the prior version's IsLatest to 0 and restarting Elsa. The restart was important, as there appears to be some caching related to the workflow newness.

TL;DR : there are multiple workflows with the same path
Check if you are building a workflow through ELSA DESIGNER and at the same time there is a workflow that is triggered when HTTP requests are made to the same URL
public class HelloWorld : IWorkflow
{
public void Build(IWorkflowBuilder builder)
{
builder
.HttpEndpoint("/hello") // this is the endpoint that is causing conflict
.When(OutcomeNames.Done)
.WriteHttpResponse(HttpStatusCode.OK, "<h1>Hello World!</h1>", "text/html");
}
}

Related

ASP.NET Core 6 MVC : adding identity failing

I'm using VS 2022, ASP.NET Core 6 MVC and Microsoft SQL Server 2019 (v15).
Git project: [https://github.com/Wizmi24/MVC_BookStore]
I'm trying to add --> new scaffolded item --> identity.
Default layout page, override all files and mine Data context
when I click add, I get this error:
There was an error running the selected code generator:
'Package restore failed. Rolling back package changes for 'MyProjectName'
I cleared NuGet Package cache as I saw it may help, but all it do is just prolong and this same error is visible after trying to install Microsoft.EntityFrameworkCore.SqlServer, which is installed. I checked the packages and made sure they are the same version (6.0.11).
I cloned your project to test, and the problem you mentioned did appear. Not sure why, but I finally got it working by updating the NuGet package:
I updated the two packages Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Relational to version 7.0.1 (you need to pay attention to the sequence when updating), then add scaffolded Identity, and I succeeded.
You can try my method, if the Identity is successfully added, but the following exception is encountered at runtime:
You need to add builder.Services.AddDbContext<MyBookContext>(); before
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<MyBookContext>();
MyBookContext is the Data context class selected when you add Identity:
In addition, if there is a 404 error in your area routing, you can refer to this document to modify it.
Hope this can help you.
Edit1:
I think it might be a problem caused by naming duplication. Please try to change the name of the context generated by Identity.
As you can see, the ApplicationDbContext generated by Identity is consistent with the ApplicationDbContext namespace in your MyBook.DataAccess:
So naming the same will cause conflict:
So you need to change the naming to avoid conflicts. For example:
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")
));
builder.Services.AddDbContext<ApplicationDbContextIdentity>();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContextIdentity>();
Edit2:
As I mentioned in the original answer, if you get a 404 error, you can try to refer to this link to fix the area routing.
The easiest way is to directly change the routing settings in Program.cs:
app.MapAreaControllerRoute(
name: "Customer",
areaName: "Customer",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
Then add the Area property to the controller:
[Area("Customer")]
public class HomeController : Controller{}
There seems to be a problem with your Repository.cs, so I changed the Index to only output a string to test the result.
public string Index()
{
return "success";
}
Test Result:
If your Repository.cs also has problems when you test it, you can make a new post for everyone to help you fix this problem(Because this question strays so far from your original question, one post is better off addressing only one question).
Good Luck.

How to load plugins when updating to MvvmCross 6.4.2 from 5.6.2

I've been tasked with maintaining a Xamarin native project using MvvmCross 5.6.2. Not knowing exactly how to approach this, I've decided to update to one major version at a time (6 first, then 7 and 8). I'm not sure why I specifically have chosen 6.4.2, but it was maybe because this was the latest version of the majority of the plugins I was using on Nuget.
So far, the update has been a success and I have been able to fix all build errors. However, when running the application, I've been getting a null reference exception which I can't fully trace.
Based on the limited application output, I've been able to determine that the problem lies somewhere in my Android's setup.cs class (I think). I've been following Nick's .NET Travels advice on MvvmCross debugging. From viewing the MvvmCross 6.4.2. source and pasting in the following code in my own overrides:
public virtual void LoadPlugins(IMvxPluginManager pluginManager)
{
Type pluginAttribute = typeof(MvxPluginAttribute);
IEnumerable<Assembly> pluginAssemblies = GetPluginAssemblies();
foreach (Assembly item in pluginAssemblies)
{
IEnumerable<Type> enumerable = item.ExceptionSafeGetTypes();
foreach (Type item2 in enumerable)
{
if (TypeContainsPluginAttribute(item2))
{
pluginManager.EnsurePluginLoaded(item2);
}
}
}
bool TypeContainsPluginAttribute(Type type)
{
object[] customAttributes = type.GetCustomAttributes(pluginAttribute, inherit: false);
return ((customAttributes != null && customAttributes.Length != 0) ? 1 : 0) > (false ? 1 : 0);
}
}
public virtual IEnumerable<Assembly> GetPluginAssemblies()
{
string mvvmCrossAssemblyName = typeof(MvxPluginAttribute).Assembly.GetName().Name;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
var test = from asmb in assemblies.AsParallel()
where AssemblyReferencesMvvmCross(asmb, mvvmCrossAssemblyName)
select asmb;
return test;
}
I'm able to see that GetPluginAssemblies doesn't return any enumerable, and the LoadPlugins method then produces the NullReferenceException. But I can't see what this NullReference actually is.
I followed the upgrading from 5 to 6 guide https://www.mvvmcross.com/documentation/upgrading/upgrade-to-mvvmcross-60.
I looked at the MvvmCross 6 and 6.4.0 release pages:
https://www.mvvmcross.com/mvvmcross-6.0.0-release/
https://www.mvvmcross.com/mvvmcross-6.4.0-release/
And I followed Benjamin Mayrargue's guide: https://medium.com/#bigoudi/upgrading-from-mvvmcross-5-to-mvvmcross-6-7ded83ecb69d
But I have been unable to load my plugins (previously they were bootstraps, but most of the guides say these can be discarded now and that loading plugins is easier).
I also attempted the answer suggested in this question How to use an mvvmcross plugin such as the file plugin.
But to no avail.
So I am asking if anyone knows a good guide or how to use plugins in MvvmCross 6.4.2.
Thank you.
Plugins are just a way to register things in the IoC Container. This is done by MvvmCross during startup using the LoadPlugins method in your Setup file.
Most of the time it should just work. However, there are some caveats.
If the Linker has gone ahead and linked away some of the plugins code, you will have a bad time. What you can do about that is to hint the mono linker to not strip the code away.
Add a LinkerPleaseInclude class and add a Include method in it that looks something like:
new MvvmCross.Plugin.Color.Platforms.Ios.Plugin().Load();
You can do that for every plugin you may want to use.
If LoadPlugins doesn't find the entry Assembly, sometimes it also does not register the plugins. You can override LoadPlugins in your Setup class and just call EnsurePluginLoaded:
public override void LoadPlugins(IMvxPluginManager pluginManager)
{
base.LoadPlugins(pluginManager);
pluginManager.EnsurePluginLoaded<MvvmCross.Plugin.Color.Platforms.Ios.Plugin>();
}
I want to thank Cheesebaron for his plugin support. I think I've fixed my issue and as it turned out, I don't think there is a plugin issue after all (yet).
Thanks to Toolmakersteve also. His suggestion for using a try catch in the OnCreate of my overridden MvxSplashScreenAppCompatActivity surfaced an issue with setting a theme for this activity. In actuality, this class was initially a MvxSplashScreenActivity.
Reverting this line, I then started getting NullReferenceExceptions on specific lines, all relating to IoC and lazy construction of singletons. The class Mvx seemed to be throwing up this error. On a sort of hunch from previous experience with my updating, I removed the MvvmCross.Platform using statement and checked what suggestions Mvx had available to it. It suggested MvvmCross and MvvmCross.Platform, so I tried the former instead. Sure enough, this moved my execution further, throwing up more Null Reference Exceptions. I also encountered one instance of failing to resolve IMvxResourceLoader from MvvmCross.Platform.Platform. Switching that to MvvmCross.Base did the trick.
This was only a chance fix through a bit of guess work. #CheeseBaron, should I add this as a note to this bit of documentation https://www.mvvmcross.com/documentation/upgrading/upgrade-to-mvvmcross-60? As mentioned, I'm as far as 6.4.2 now, so I'm not certain this is the right place for it.
I've got a few bugs with embedded resources to fix now, but if I encounter any more that are relevant to my question, I'll list them here.

How to set Execution Timeout in Hotchocolate 10.4.3

we are using Hotchocolate 10.4.3 for my .net core service.
we are using code first approach.
All settings are in startup.cs exactly similar to their Star War example.
Hotchocolate web site says default timeout for request is 30 sec but I found my application throwing Transaction error after 1 min.
I want to increase that to 2 min.
Also why server still executes everything even after timeout exception.
I always see Transaction error at end after all my code gets execute properly.
If everything is going to run properly why to even then throw error?
I'm still learning graphql. Please correct me if anything sounds incorrect.
In HotChocolate v10, you can set the execution timeout when you add the service in your Startup's ConfigureServices() method:
services.AddGraphQL(
SchemaBuilder.New()
.AddQueryType<Query>()
.Create(),
new QueryExecutionOptions { ExecutionTimeout = TimeSpan.FromMinutes(2) });
They have a good repo of examples here: https://github.com/ChilliCream/hotchocolate-examples
Documentation on the execution options: https://chillicream.com/docs/hotchocolate/v10/execution-engine/execution-options
EDIT: In v11, the syntax has changed:
services
.AddGraphQLServer()
.AddQueryType<Query>()
.SetRequestOptions(_ => new HotChocolate.Execution.Options.RequestExecutorOptions { ExecutionTimeout = TimeSpan.FromMinutes(10) });

How to debug a plugin in on-line version?

I've created a plugin and registered it using hte registration tool. I've also added a step that is supposed to handle a message of creation of an instance. Sadly, the intended behavior doesn't occur.
My guess is that something inside the plugin crashes but I have no idea on how to debug it. Setting up breakpoints is not going to work agains on-line version, I understand, so I'm not even trying.
For legal and technical reasons, I won't be able to lift over the solution to an on-premise installation, neither. Is guessing my only option?
For server-side (plugins) I'm using ITracingService. For client-side I log everything to console. The downside with the first is that you actually need to crash the execution to get to see anything. The downside with the latter is that plugins sometimes get executed without GUI being invoked at all.
When it comes to heavier projects, I simply set up a WCF web service that I call from the plugin and write to that. That way, on one screen, I'm executing the plugin while on the other, I'm getting a nice log file (or just put the sent information to on the screen).
You could, for instance, start with a very basic update of a field on the instance of your entity that's being created. When you have that working, you can always fall back to the last working version. If you don't even get that to work, it mean, probably, that you're setting up the plugin registration incorrectly.
A very efficient way would be to lift over the solution to an on-premise version where you have full control but I see in your question that it's not en option.
In case you could lift the solution to an on-premise version, here's a link on how to debug plugins.
Don't forget that you also have access to the ITracingService.
You can get a reference to it in your Execute method and then write to it every so often in your code to log variables or courses of action that you are attempting or have succeeded with. You can also use it to surface more valuable information when an exception occurs.
It's basically like writing to a console. Then, if anything causes the plug-in to crash at runtime then you can see everything that you've traced when you click Download Log File on the error shown to the user.
Beware though - unless your plug-in actually throws an exception (deliberate or otherwise) then you have no access to whatever was traced.
Example:
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the execution context from the service provider.
IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(
typeof(IPluginExecutionContext));
// Get a reference to the tracing service.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Getting entity from InputParameters...");
// may fail for some messages, since "Target" is not present
var myEntity = (Entity)context.InputParameters["Target"];
tracingService.Trace("Got entity OK");
// some other logic here...
}
catch (FaultException<OrganizationServiceFault> ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = (FaultException<OrganizationServiceFault>)ex.InnerException;
_trace.Trace(ex.ToString());
}
throw new InvalidPluginExecutionException(
string.Format("An error occurred in your plugin: {0}", ex));
}
catch (Exception ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = ex.InnerException;
_trace.Trace(ex.ToString());
}
throw;
}
}

"There is already an open DataReader..." error when using the Database.SetInitializer in the Global.Asax ApplciaitonStart

I am wondering if anyone else has had an issue with running the DB initializer from the global asax?
I have this in the ApplicationStart:
Database.SetInitializer(new MyInitializer());
That runs fine, after that once my application has started I try a login Method i created in my services. It fails when it tries to open the context.
My test application is setup almost the same way and doesn't have an issue.
Any thoughts?
Update:
I tried adding the MultipleActiveResultSets=True and now I am getting this error:
The underlying provider failed on Open.
Update 2:
Well, it turns out that my application loads while the initializer is still finishing. That is why I was getting those errors. So, what I figured out is that part of the app loads and then it must request something from the DB (at which point it created the DB and seeds it). At that point part of the application has loaded, but you don't know that the initializer is still running.
Like I sad in my updates, the DB wasn't getting created until after most of the application had run already. It was still running even though, as a user, you wouldn't know it. So I created an initialization project and added this class:
public static class InitializeAndSeed
{
public static void Initialize()
{
Database.SetInitializer(new MyContextInitializer());
using (var db = new MyContext())
{
db.Database.Initialize(false);
}
}
}
In my Applicaiton_Start() I call the InitializeAndSeed.Initialize(). Worked perfectly.
This article helped me figure that out.

Resources