Skip to content

Commit a082b58

Browse files
authored
Merge pull request #276 from aspnetzero/pr/2759
Update Elsa mvc documentation
2 parents be99556 + 3291acb commit a082b58

File tree

2 files changed

+66
-54
lines changed

2 files changed

+66
-54
lines changed

blog-posts/en/integrating-elsa-with-asp.net-zero.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ private void ConfigureElsa(IServiceCollection services)
7676
}
7777
```
7878

79+
> **Note:** ReplaceResultFilter is explained in the next section.
80+
7981
In this configuration, we are configuring Elsa to use existing ASP.NET Zero database and we configure Elsa with Default connection string. In order for this configuration to work, we need to add below section to `appsettings.json`.
8082

8183
````json
@@ -173,6 +175,8 @@ private void ReplaceResultFilter(MvcOptions options)
173175
This method replaces `AbpResultFilter` with `ElsaResultFilter`. Here is the content of `ElsaResultFilter`;
174176

175177
```c#
178+
using Elsa.Server.Api.Endpoints.Activities;
179+
176180
public class ElsaResultFilter : IResultFilter, ITransientDependency
177181
{
178182
private readonly IAbpAspNetCoreConfiguration _configuration;
@@ -230,6 +234,8 @@ public class ElsaResultFilter : IResultFilter, ITransientDependency
230234
}
231235
```
232236

237+
> **Note:** `using Elsa.Server.Api.Endpoints.Activities;` is required for `List` class.
238+
233239
### Configure Method
234240

235241
The additions of Configure method are shown in the code block below;
@@ -275,7 +281,7 @@ public override void Initialize()
275281
// existing code blocks
276282
277283
// Register controllers inside ELSA
278-
Register(typeof(Elsa.Server.Api.Endpoints.WebhookDefinitions.List).GetAssembly());
284+
Register(typeof(Elsa.Server.Api.Endpoints.WorkflowDefinitions.List).GetAssembly());
279285
Register(typeof(Elsa.Server.Api.Endpoints.WorkflowDefinitions.Save).GetAssembly());
280286
}
281287

docs/en/Core-Mvc-Elsa-Integration.md

Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ In order to start integrating Elsa with ASP.NET Zero, first follow ASP.NET Zero'
1010

1111
## Adding Elsa Packages
1212

13-
After creating the empty project, we need to add required Elsa NuGet packages to our project. Elsa document uses ```Elsa.Persistence.EntityFramework.Sqlite``` for persistence but we will use ```Elsa.Persistence.EntityFramework.SqlServer``` because ASP.NET Zero use SQL Server by default. So, add packages below to your *.Web.Mvc project.
13+
After creating the empty project, we need to add required Elsa NuGet packages to our project. Elsa document uses `Elsa.Persistence.EntityFramework.Sqlite` for persistence but we will use `Elsa.Persistence.EntityFramework.SqlServer` because ASP.NET Zero use SQL Server by default. So, add packages below to your `*.Web.Mvc` project.
1414

1515
* [Elsa](https://www.nuget.org/packages/Elsa)
1616
* [Elsa.Activities.Http](https://www.nuget.org/packages/Elsa.Activities.Http)
@@ -23,18 +23,18 @@ After creating the empty project, we need to add required Elsa NuGet packages to
2323

2424
### ConfigureServices Method
2525

26-
After adding Elsa NuGet packages, we need to configure Elsa in Startup.cs. So, open ```Startup.cs``` under ***.Web.Mvc/Startup/** and configure it as shown below;
26+
After adding Elsa NuGet packages, we need to configure Elsa in Startup.cs. So, open `Startup.cs` under `.Web.Mvc/Startup/` and configure it as shown below;
2727

28-
````c#
28+
```c#
2929
public IServiceProvider ConfigureServices(IServiceCollection services)
3030
{
3131
ConfigureElsa(services);
3232

3333
// Existing code blocks
3434
}
35-
````
35+
```
3636

37-
````c#
37+
```c#
3838
private void ConfigureElsa(IServiceCollection services)
3939
{
4040
services.AddElsa(elsa =>
@@ -74,9 +74,11 @@ private void ConfigureElsa(IServiceCollection services)
7474
ReplaceResultFilter(options);
7575
});
7676
}
77-
````
77+
```
78+
79+
> **Note:** ReplaceResultFilter is explained in the next section.
7880
79-
In this configuration, we are configuring Elsa to use existing ASP.NET Zero database and we configure Elsa with Default connection string. In order for this configuration to work, we need to add below section to **appsettings.json**.
81+
In this configuration, we are configuring Elsa to use existing ASP.NET Zero database and we configure Elsa with Default connection string. In order for this configuration to work, we need to add below section to `appsettings.json`.
8082

8183
````json
8284
"Elsa": {
@@ -96,9 +98,9 @@ There are some special configuration points here which doesn't exist in default
9698
elsa.UseAutoMapper(() => { });
9799
````
98100

99-
Both Elsa and ASP.NET Boilerplate creates a ```MapperConfiguration``` and uses it to create an `IMapper`. Because of this, if we don't add this line to Elsa configuration, the app will only use Elsa's AutoMapper configuration. But, after making this configuration, we need to configure Elsa's AutoMapper mappings in our app manually. In order to do this, go to ***WebMvcModule** and add below lines to its ```PreInitialize``` method.
101+
Both Elsa and ASP.NET Boilerplate creates a `MapperConfiguration` and uses it to create an `IMapper`. Because of this, if we don't add this line to Elsa configuration, the app will only use Elsa's **AutoMapper** configuration. But, after making this configuration, we need to configure Elsa's AutoMapper mappings in our app manually. In order to do this, go to `*WebMvcModule` and add below lines to its `PreInitialize` method.
100102

101-
````
103+
```
102104
// ELSA AutoMapper
103105
Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
104106
{
@@ -115,11 +117,11 @@ Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
115117
config.CreateMap<WorkflowDefinition, WorkflowDefinition>();
116118
config.CreateMap<WorkflowInstance, WorkflowInstance>();
117119
});
118-
````
120+
```
119121

120122
#### API Versioning
121123

122-
````
124+
```
123125
services.AddElsaApiEndpoints();
124126
services.Configure<ApiVersioningOptions>(options =>
125127
{
@@ -130,9 +132,9 @@ services.Configure<RouteOptions>(options =>
130132
{
131133
options.LowercaseUrls = false;
132134
});
133-
````
135+
```
134136

135-
ASP.NET Zero doesn't support API versioning and Elsa uses it by default. But, disabling ```UseApiBehavior``` makes ASP.NET Zero and Elsa to work together. ```AddElsaApiEndpoints``` configures ```LowercaseUrls``` of ```RouteOptions``` to true but ASP.NET Zero requires case sensitive URLs. So, we are converting ```LowercaseUrls``` of ```RouteOptions``` to false.
137+
ASP.NET Zero doesn't support API versioning and Elsa uses it by default. But, disabling `UseApiBehavior` makes ASP.NET Zero and Elsa to work together. `AddElsaApiEndpoints` configures `LowercaseUrls` of `RouteOptions` to true but ASP.NET Zero requires case sensitive URLs. So, we are converting `LowercaseUrls` of `RouteOptions` to false.
136138

137139
#### Result Filtering
138140

@@ -143,11 +145,11 @@ services.PostConfigure<MvcOptions>(options =>
143145
});
144146
````
145147

146-
ASP.NET Zero wraps JSON results by default and adds some additional fields to JSON result. The actual result is accessed by ```result ``` property of the returned JSON result. But, Elsa doesn't work this way, so we should ignore result wrapping for Elsa's controllers. Unfortunately, ASP.NET Zero doesn't provide an easy configuration for doing that. Because of that, we need to replace default result filter with our own custom result filter using the configuration above.
148+
ASP.NET Zero **wraps JSON** results by default and adds some additional fields to JSON result. The actual result is accessed by `result` property of the returned JSON result. But, Elsa doesn't work this way, so we should **ignore result wrapping** for Elsa's controllers. Unfortunately, ASP.NET Zero doesn't provide an easy configuration for doing that. Because of that, we need to replace default result filter with our own **custom result filter** using the configuration above.
147149

148-
Here is the content of ```ReplaceResultFilter``` method;
150+
Here is the content of `ReplaceResultFilter` method;
149151

150-
````c#
152+
```c#
151153
private void ReplaceResultFilter(MvcOptions options)
152154
{
153155
for (var index = options.Filters.Count - 1; index >= 0; --index)
@@ -168,11 +170,13 @@ private void ReplaceResultFilter(MvcOptions options)
168170
break;
169171
}
170172
}
171-
````
173+
```
172174

173-
This method replaces ```AbpResultFilter``` with ```ElsaResultFilter```. Here is the content of ```ElsaResultFilter```;
175+
This method replaces `AbpResultFilter` with `ElsaResultFilter`. Here is the content of `ElsaResultFilter`;
176+
177+
```c#
178+
using Elsa.Server.Api.Endpoints.Activities;
174179

175-
````c#
176180
public class ElsaResultFilter : IResultFilter, ITransientDependency
177181
{
178182
private readonly IAbpAspNetCoreConfiguration _configuration;
@@ -228,13 +232,15 @@ public class ElsaResultFilter : IResultFilter, ITransientDependency
228232
?? defaultValue;
229233
}
230234
}
231-
````
235+
```
236+
237+
> **Note:** `using Elsa.Server.Api.Endpoints.Activities;` is required for `List` class.
232238
233239
### Configure Method
234240

235241
The additions of Configure method are shown in the code block below;
236242

237-
````c#
243+
```c#
238244
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
239245
{
240246
// existing code blocks
@@ -258,24 +264,24 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
258264

259265
// existing code blocks
260266
}
261-
````
267+
```
262268

263269
There are two additions here;
264270

265-
1. ```app.UseHttpActivities();``` this line allows Elsa to handle HTTP request and execute if there are any workflows related to HTTP activities.
266-
2. ```endpoints.MapFallbackToPage("/_Host");``` this line redirects all not found requests to _Host.cshtml page which we will create in the next section. This page will contain Elsa Dashboard source code.
271+
1. `app.UseHttpActivities();` this line allows Elsa to handle HTTP request and execute if there are any workflows related to HTTP activities.
272+
2. `endpoints.MapFallbackToPage("/_Host");` this line redirects all not found requests to `_Host.cshtml` page which we will create in the next section. This page will contain Elsa Dashboard source code.
267273

268274
### Elsa Controllers
269275

270276
By default Elsa controllers are not registered in ASP.NET Zero's dependency injection system. In order to do that, we must register Elsa Conrollers as shown below in the Initialize method of the MVC Wed Module;
271277

272-
````c#
278+
```c#
273279
public override void Initialize()
274280
{
275281
// existing code blocks
276282
277283
// Register controllers inside ELSA
278-
Register(typeof(Elsa.Server.Api.Endpoints.WebhookDefinitions.List).GetAssembly());
284+
Register(typeof(Elsa.Server.Api.Endpoints.WorkflowDefinitions.List).GetAssembly());
279285
Register(typeof(Elsa.Server.Api.Endpoints.WorkflowDefinitions.Save).GetAssembly());
280286
}
281287

@@ -312,13 +318,13 @@ private void Register(Assembly assembly)
312318
.LifestyleTransient()
313319
);
314320
}
315-
````
321+
```
316322

317323
## Elsa Dashboard
318324

319-
In order to add Elsa Dashboard into ASP.NET Zero, create a folder named **Pages** under the MVC project and create a razor page named ```_Host.cshtml``` with the content below;
325+
In order to add Elsa Dashboard into ASP.NET Zero, create a folder named `Pages` under the MVC project and create a razor page named `_Host.cshtml` with the content below;
320326

321-
````html
327+
```html
322328
@page "/"
323329
@{
324330
var serverUrl = $"{Request.Scheme}://{Request.Host}";
@@ -340,11 +346,11 @@ In order to add Elsa Dashboard into ASP.NET Zero, create a folder named **Pages*
340346
<elsa-studio-root server-url="@serverUrl" monaco-lib-path="_content/Elsa.Designer.Components.Web/monaco-editor/min"></elsa-studio-root>
341347
</body>
342348
</html>
343-
````
349+
```
344350

345-
ASP.NET Zero uses ``` WebHostBuilder``` in its Program.cs but it has some problems with embedded static files. Elsa provides styles and scripts of its dashboard as static files. In order to load Elsa's static files, change the ```Program.cs``` as shown below;
351+
ASP.NET Zero uses `WebHostBuilder` in its Program.cs but it has some problems with embedded static files. Elsa provides styles and scripts of its dashboard as static files. In order to load Elsa's static files, change the `Program.cs` as shown below;
346352

347-
````c#
353+
```c#
348354
public class Program
349355
{
350356
public static void Main(string[] args)
@@ -367,13 +373,13 @@ public class Program
367373
.UseStartup<Startup>();
368374
}
369375
}
370-
````
376+
```
371377

372378
## UserManager
373379

374-
During the integration of Elsa, we faced an error of Serialization and Deserialization of ```IdentityOptions``` in UserManager's ```InitializeOptionsAsync``` method. To overcome this problem, you should override the related method in UserManager.cs as shown below;
380+
During the integration of Elsa, we faced an error of Serialization and Deserialization of `IdentityOptions` in UserManager's `InitializeOptionsAsync` method. To overcome this problem, you should override the related method in `UserManager.cs` as shown below;
375381

376-
````c#
382+
```c#
377383
public override async Task InitializeOptionsAsync(int? tenantId)
378384
{
379385
Options = new IdentityOptions
@@ -473,50 +479,50 @@ private Task<T> GetSettingValueAsync<T>(string settingName, int? tenantId) where
473479
? _settingManager.GetSettingValueForApplicationAsync<T>(settingName)
474480
: _settingManager.GetSettingValueForTenantAsync<T>(settingName, tenantId.Value);
475481
}
476-
````
482+
```
477483

478-
This approach manually creates a ```IdentityOptions``` and manually sets its fields one by one. The previous version uses AutoMapper which causes a problem.
484+
This approach manually creates a `IdentityOptions` and manually sets its fields one by one. The previous version uses **AutoMapper** which causes a problem.
479485

480486
## Navigation
481487

482488
Finally, let's add Elsa Dashboard as a menu item to our app. In order to do that, first create a new localization in the localization xml file as shown below;
483489

484-
````xml
490+
```xml
485491
<text name="Workflows">Workflows</text>
486-
````
492+
```
487493

488-
After that, define a constant in **AppPageNames.cs** as shown below right under ```DynamicEntityProperties``` definition;
494+
After that, define a constant in `AppPageNames.cs` as shown below right under `DynamicEntityProperties` definition;
489495

490-
````c#
496+
```c#
491497
public const string Elsa = "Elsa.Main";
492-
````
498+
```
493499

494-
Let's also define a permission for our new page. To do that, create a const in **AppPermisisons.cs** as shown below right under ```Pages_Administration_DynamicEntityPropertyValue_Delete``` ;
500+
Let's also define a permission for our new page. To do that, create a const in `AppPermisisons.cs` as shown below right under `Pages_Administration_DynamicEntityPropertyValue_Delete` ;
495501

496-
````c#
502+
```c#
497503
public const string Pages_Workflows = "Pages.Workflows";
498-
````
504+
```
499505

500-
and define a permission in **AppAuthorizationProvider.cs** as show below right after definition of ```AppPermissions.Pages_DemoUiComponents``` ;
506+
and define a permission in `AppAuthorizationProvider.cs` as show below right after definition of `AppPermissions.Pages_DemoUiComponents` ;
501507

502-
````c#
508+
```c#
503509
pages.CreateChildPermission(AppPermissions.Pages_Workflows, L("Workflows"));
504-
````
510+
```
505511

506-
after all, add a menu item to **AppNavigationProvider.cs** as shown below;
512+
after all, add a menu item to `AppNavigationProvider.cs` as shown below;
507513

508-
````c#
514+
```c#
509515
.AddItem(new MenuItemDefinition(
510516
AppPageNames.Common.Elsa,
511517
L("Workflows"),
512518
url: "/Workflows",
513519
icon: "flaticon-map",
514520
permissionDependency: new SimplePermissionDependency(AppPermissions.Pages_Workflows)
515521
)
516-
````
522+
```
517523

518-
That's all. You can now run the application and navigate to ```/Workflows``` page and see Elsa Dashboard.
524+
That's all. You can now run the application and navigate to `/Workflows` page and see Elsa Dashboard.
519525

520526
## Sample Workflow
521527

522-
You can create a sample workflow as explained in [Elsa Documentation](https://elsa-workflows.github.io/elsa-core/docs/next/quickstarts/quickstarts-aspnetcore-server-dashboard-and-api-endpoints#the-workflow). This sample workflow starts with a request to ```/hello-world``` endpoint and returns the specified HTTP response.
528+
You can create a sample workflow as explained in [Elsa Documentation](https://elsa-workflows.github.io/elsa-core/docs/next/quickstarts/quickstarts-aspnetcore-server-dashboard-and-api-endpoints#the-workflow). This sample workflow starts with a request to `/hello-world` endpoint and returns the specified HTTP response.

0 commit comments

Comments
 (0)