Base solution for your next web application
Open Closed

Elsa 2 Integration with AspNetZero 10.3 #10352


User avatar
0
logitsolutions created

Prerequisites

Zero 10.3.0 Angular .net core

Integrating Elsa 2 with my project

Code as :

using System; using System.IO; using System.Linq; using System.Reflection; using Abp.AspNetCore; using Abp.AspNetCore.Configuration; using Abp.AspNetCore.Mvc.Antiforgery; using Abp.AspNetCore.Mvc.Extensions; using Abp.AspNetCore.SignalR.Hubs; using Abp.AspNetZeroCore.Web.Authentication.JwtBearer; using Abp.Castle.Logging.Log4Net; using Abp.Extensions; using Abp.Hangfire; using Abp.PlugIns; using Castle.Facilities.Logging; using Hangfire; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using acslog.Authorization; using acslog.Configuration; using acslog.EntityFrameworkCore; using acslog.Identity; using acslog.Web.Chat.SignalR; using acslog.Web.Common; using Swashbuckle.AspNetCore.Swagger; using acslog.Web.IdentityServer; using acslog.Web.Swagger; using Stripe; using ILoggerFactory = Microsoft.Extensions.Logging.ILoggerFactory; using GraphQL.Server; using GraphQL.Server.Ui.Playground; using HealthChecks.UI.Client; using IdentityServer4.Configuration; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; using acslog.Configure; using acslog.Schemas; using acslog.Web.HealthCheck; using Newtonsoft.Json.Serialization; using Owl.reCAPTCHA; using HealthChecksUISettings = HealthChecks.UI.Configuration.Settings; using Microsoft.AspNetCore.Server.Kestrel.Https; using Elsa.Persistence.EntityFramework.Core.Extensions; using Elsa.Persistence.EntityFramework.SqlServer; namespace acslog.Web.Startup { public class Startup { private const string DefaultCorsPolicyName = "localhost";

    private readonly IConfigurationRoot _appConfiguration;
    private readonly IWebHostEnvironment _hostingEnvironment;

    public Startup(IWebHostEnvironment env)
    {
        _hostingEnvironment = env;
        _appConfiguration = env.GetAppConfiguration();
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {

        var elsaSection = _appConfiguration.GetSection("Elsa");
        // services.AddElsa();
         services.AddElsa(elsa => elsa.UseEntityFrameworkPersistence(options => options.UseSqlServer(_appConfiguration.GetConnectionString("Elsa")))
                .AddHttpActivities(elsaSection.GetSection("Server").Bind)
                .AddJavaScriptActivities()
                );

        //MVC
        services.AddControllersWithViews(options =>
        {
            options.Filters.Add(new AbpAutoValidateAntiforgeryTokenAttribute());
        }).AddNewtonsoftJson();

        services.AddSignalR();

        //Configure CORS for angular2 UI
        services.AddCors(options =>
        {
            options.AddPolicy(DefaultCorsPolicyName, builder =>
            {
                //App:CorsOrigins in appsettings.json can contain more than one address with splitted by comma.
                builder
                    .WithOrigins(
                        // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
                        _appConfiguration["App:CorsOrigins"]
                            .Split(",", StringSplitOptions.RemoveEmptyEntries)
                            .Select(o => o.RemovePostFix("/"))
                            .ToArray()
                    )
                    .SetIsOriginAllowedToAllowWildcardSubdomains()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });
        });

        if (bool.Parse(_appConfiguration["KestrelServer:IsEnabled"]))
        {
            ConfigureKestrel(services);
        }

        IdentityRegistrar.Register(services);
        AuthConfigurer.Configure(services, _appConfiguration);

        //Identity server
        if (bool.Parse(_appConfiguration["IdentityServer:IsEnabled"]))
        {
            IdentityServerRegistrar.Register(services, _appConfiguration, options =>
                options.UserInteraction = new UserInteractionOptions()
                {
                    LoginUrl = "/UI/Login",
                    LogoutUrl = "/UI/LogOut",
                    ErrorUrl = "/Error"
                });
        }

        if (WebConsts.SwaggerUiEnabled)
        {
            //Swagger - Enable this line and the related lines in Configure method to enable swagger UI
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo() {Title = "acslog API", Version = "v1"});
                options.DocInclusionPredicate((docName, description) => true);
                options.ParameterFilter<SwaggerEnumParameterFilter>();
                options.SchemaFilter<SwaggerEnumSchemaFilter>();
                options.OperationFilter<SwaggerOperationIdFilter>();
                options.OperationFilter<SwaggerOperationFilter>();
                options.CustomDefaultSchemaIdSelector();
            }).AddSwaggerGenNewtonsoftSupport();
        }

        //Recaptcha
        services.AddreCAPTCHAV3(x =>
        {
            x.SiteKey = _appConfiguration["Recaptcha:SiteKey"];
            x.SiteSecret = _appConfiguration["Recaptcha:SecretKey"];
        });

        if (WebConsts.HangfireDashboardEnabled)
        {
            //Hangfire(Enable to use Hangfire instead of default job manager)
            services.AddHangfire(config =>
            {
                config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default"));
            });
        }

        if (WebConsts.GraphQL.Enabled)
        {
            services.AddAndConfigureGraphQL();
        }

        if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
        {
            services.AddAbpZeroHealthCheck();

            var healthCheckUISection = _appConfiguration.GetSection("HealthChecks")?.GetSection("HealthChecksUI");

            if (bool.Parse(healthCheckUISection["HealthChecksUIEnabled"]))
            {
                services.Configure<HealthChecksUISettings>(settings =>
                {
                    healthCheckUISection.Bind(settings, c => c.BindNonPublicProperties = true);
                });
                services.AddHealthChecksUI()
                    .AddInMemoryStorage();
            }
        }

        //Configure Abp and Dependency Injection
        return services.AddAbp<acslogWebHostModule>(options =>
        {
            //Configure Log4Net logging
            options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                f => f.UseAbpLog4Net().WithConfig(_hostingEnvironment.IsDevelopment()
                    ? "log4net.config"
                    : "log4net.Production.config")
            );

            options.PlugInSources.AddFolder(Path.Combine(_hostingEnvironment.WebRootPath, "Plugins"),
                SearchOption.AllDirectories);
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        //Initializes ABP framework.
        app.UseAbp(options =>
        {
            options.UseAbpRequestLocalization = false; //used below: UseAbpRequestLocalization
        });

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseStatusCodePagesWithRedirects("~/Error?statusCode={0}");
            app.UseExceptionHandler("/Error");
        }

        app.UseStaticFiles();
        app.UseRouting();

        app.UseCors(DefaultCorsPolicyName); //Enable CORS!

        app.UseAuthentication();
        app.UseJwtTokenMiddleware();

        if (bool.Parse(_appConfiguration["IdentityServer:IsEnabled"]))
        {
            app.UseJwtTokenMiddleware("IdentityBearer");
            app.UseIdentityServer();
        }

        app.UseAuthorization();

        using (var scope = app.ApplicationServices.CreateScope())
        {
            if (scope.ServiceProvider.GetService<DatabaseCheckHelper>()
                .Exist(_appConfiguration["ConnectionStrings:Default"]))
            {
                app.UseAbpRequestLocalization();
            }
        }

        if (WebConsts.HangfireDashboardEnabled)
        {
            //Hangfire dashboard &server(Enable to use Hangfire instead of default job manager)
            app.UseHangfireDashboard(WebConsts.HangfireDashboardEndPoint, new DashboardOptions
            {
                Authorization = new[]
                    {new AbpHangfireAuthorizationFilter(AppPermissions.Pages_Administration_HangfireDashboard)}
            });
            app.UseHangfireServer();
        }

        if (bool.Parse(_appConfiguration["Payment:Stripe:IsActive"]))
        {
            StripeConfiguration.ApiKey = _appConfiguration["Payment:Stripe:SecretKey"];
        }

        if (WebConsts.GraphQL.Enabled)
        {
            app.UseGraphQL<MainSchema>();
            if (WebConsts.GraphQL.PlaygroundEnabled)
            {
                app.UseGraphQLPlayground(
                    new GraphQLPlaygroundOptions()); //to explorer API navigate https://*DOMAIN*/ui/playground
            }
        }

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<AbpCommonHub>("/signalr");
            endpoints.MapHub<ChatHub>("/signalr-chat");

            endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapControllers();
            if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
            {
                endpoints.MapHealthChecks("/health", new HealthCheckOptions()
                {
                    Predicate = _ => true,
                    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
                });
            }
            
            app.ApplicationServices.GetRequiredService<IAbpAspNetCoreConfiguration>().EndpointConfiguration.ConfigureAllEndpoints(endpoints);
        });

        if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
        {
            if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksUI:HealthChecksUIEnabled"]))
            {
                app.UseHealthChecksUI();
            }
        }

        if (WebConsts.SwaggerUiEnabled)
        {
            // Enable middleware to serve generated Swagger as a JSON endpoint
            app.UseSwagger();
            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)

            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint(_appConfiguration["App:SwaggerEndPoint"], "acslog API V1");
                options.IndexStream = () => Assembly.GetExecutingAssembly()
                    .GetManifestResourceStream("acslog.Web.wwwroot.swagger.ui.index.html");
                options.InjectBaseUrl(_appConfiguration["App:ServerRootAddress"]);
            }); //URL: /swagger
        }
    }

    private void ConfigureKestrel(IServiceCollection services)
    {
        services.Configure<Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions>(options =>
        {
            options.Listen(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 443),
                listenOptions =>
                {
                    var certPassword = _appConfiguration.GetValue<string>("Kestrel:Certificates:Default:Password");
                    var certPath = _appConfiguration.GetValue<string>("Kestrel:Certificates:Default:Path");
                    var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath,
                        certPassword);
                    listenOptions.UseHttps(new HttpsConnectionAdapterOptions()
                    {
                        ServerCertificate = cert
                    });
                });
        });
    }
}

}

Error

After build while login to Server Swagger Api

An unhandled exception occurred while processing the request. ArgumentException: Could not cast or convert from System.String to System.Type. Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(object value, Type initialType, Type targetType)

JsonSerializationException: Error converting value "acslog.Authentication.TwoFactor.Google.GoogleAuthenticatorProvider" to type 'System.Type'. Path 'Tokens.ProviderMap.GoogleAuthenticator.ProviderType', line 1, position 1042. Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType)

Startup.cs


32 Answer(s)
  • User Avatar
    0
    olmy90 created

    We can't get it up and running - we use Version 10.2 with Angular + .NET CORE. Is it s problem with version and we need to upgrade to ASPZERO 10.3 or higher?

  • User Avatar
    0
    olmy90 created

    Got it up and running now - but deployment version has a problem:

    GEThttps://XXX/assets/statichtml/workflow-dashboard.html [HTTP/1.1 406 Not Acceptable 19ms]

    ERROR Object { headers: {…}, status: 406, statusText: "Not Acceptable", url: "https://dp1.pli-solutions.de/assets/statichtml/workflow-dashboard.html", ok: false, name: "HttpErrorResponse", message: "Http failure response for https://dp1.pli-solutions.de/assets/statichtml/workflow-dashboard.html: 406 Not Acceptable", error: "<!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;>\r\n<html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;>\r\n<head>\r\n<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot;/>\r\n<title>406 - Client browser does not accept the MIME type of the requested page.</title>\r\n<style type=&quot;text/css&quot;>\r\n<!--\r\nbody{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}\r\nfieldset{padding:0 15px 10px 15px;} \r\nh1{font-size:2.4em;margin:0;color:#FFF;}\r\nh2{font-size:1.7em;margin:0;color:#CC0000;} \r\nh3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} \r\n#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:&quot;trebuchet MS&quot;, Verdana, sans-serif;color:#FFF;\r\nbackground-color:#555555;}\r\n#content{margin:0 0 0 2%;position:relative;}\r\n.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}\r\n-->\r\n</style>\r\n</head>\r\n<body>\r\n<div id=&quot;header&quot;><h1>Server Error</h1></div>\r\n<div id=&quot;content&quot;>\r\n <div class=&quot;content-container&quot;><fieldset>\r\n <h2>406 - Client browser does not accept the MIME type of the requested page.</h2>\r\n <h3>The page you are looking for cannot be opened by your browser because it has a file name extension that your browser does not accept.</h3>\r\n </fieldset></div>\r\n</div>\r\n</body>\r\n</html>\r\n" } ​ error: "<!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;>\r\n<html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;>\r\n<head>\r\n<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot;/>\r\n<title>406 - Client browser does not accept the MIME type of the requested page.</title>\r\n<style type=&quot;text/css&quot;>\r\n<!--\r\nbody{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}\r\nfieldset{padding:0 15px 10px 15px;} \r\nh1{font-size:2.4em;margin:0;color:#FFF;}\r\nh2{font-size:1.7em;margin:0;color:#CC0000;} \r\nh3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} \r\n#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:&quot;trebuchet MS&quot;, Verdana, sans-serif;color:#FFF;\r\nbackground-color:#555555;}\r\n#content{margin:0 0 0 2%;position:relative;}\r\n.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}\r\n-->\r\n</style>\r\n</head>\r\n<body>\r\n<div id=&quot;header&quot;><h1>Server Error</h1></div>\r\n<div id=&quot;content&quot;>\r\n <div class=&quot;content-container&quot;><fieldset>\r\n <h2>406 - Client browser does not accept the MIME type of the requested page.</h2>\r\n <h3>The page you are looking for cannot be opened by your browser because it has a file name extension that your browser does not accept.</h3>\r\n </fieldset></div>\r\n</div>\r\n</body>\r\n</html>\r\n" ​ headers: Object { normalizedNames: Map(0), lazyUpdate: null, lazyInit: lazyInit() } ​ message: "Http failure response for https://XXX/assets/statichtml/workflow-dashboard.html: 406 Not Acceptable" ​ name: "HttpErrorResponse" ​ ok: false ​ status: 406 ​ statusText: "Not Acceptable" ​ url: "https://XXX/assets/statichtml/workflow-dashboard.html" ​ <prototype>: Object { … } ​​ constructor: class I { constructor(e) }​​ <prototype>: Object { … }

  • User Avatar
    0
    olmy90 created

    any idea?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @olmy90

    Could this be related to this problem and not Elsa ? Could you try this after fixing this problem

  • User Avatar
    0
    pliaspzero created

    I got this error now on IIS deployment @ismcagdas

    Uncaught SyntaxError: Unexpected token '<' elsa-workflows-studio.esm.js:1 Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

  • User Avatar
    0
    pliaspzero created

    this is our html for the Designer

    <!DOCTYPE html> <html lang="en">

    <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Elsa Workflows</title> <link rel="icon" type="image/png" sizes="32x32" href="{serviceurl}/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="{serviceurl}/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-16x16.png"> <link rel="stylesheet" href="{serviceurl}/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/fonts/inter/inter.css"> <link rel="stylesheet" href="{serviceurl}/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/styles/tailwind.css"> <script src="{serviceurl}/_content/Elsa.Designer.Components.Web/monaco-editor/min/vs/loader.js"></script> <script type="module" src="{serviceurl}/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.esm.js"></script> </head>

    <body class="h-screen" style="background-size: 30px 30px; background-image: url({serviceurl}/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/tile.png); background-color: #FBFBFB;"> <elsa-studio-root server-url="{serviceurl}" monaco-lib-path="{serviceurl}/_content/Elsa.Designer.Components.Web/monaco-editor/min"> <elsa-studio-dashboard></elsa-studio-dashboard> </elsa-studio-root> </body>

    </html>

  • User Avatar
    0
    ismcagdas created
    Support Team

    @pliaspzero could you send your app's URL to [email protected] ? I will try to understand if this is related to AspNet Zero or not.