Base solution for your next web application

Activities of "quTIP"

Thanks for the replies,

My issue is solved by doing the following:

1- Updating My Module to be like this:

public class SalesVeeFunctionAppModule : AbpModule
{
  
    public override void PreInitialize()
    {
        var configuration = GetConfiguration();

        Configuration.BackgroundJobs.IsJobExecutionEnabled = false;

        Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);
        Configuration.UnitOfWork.IsTransactional = false;

        

        //Use database for language management
        Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();

        //**this line solve my issue**
        Configuration.Modules.AspNetZero().LicenseCode = configuration["AbpZeroLicenseCode"];
        Configuration.EntityHistory.IsEnabled = true;
        Configuration.EntityHistory.Selectors.Add("BookentaEntities", typeof(User), typeof(Tenant));

  
    }
    private static IConfigurationRoot GetConfiguration()
    {
        return AppConfigurations.Get(Directory.GetCurrentDirectory(), addUserSecrets: true);
    }
    public override void Initialize()
    { 
            IocManager.RegisterAssemblyByConvention(typeof(SalesVeeFunctionAppModule).GetAssembly());
       
    }

    
}

2- Updating my program.cs to be like this:

using Abp;
using Abp.AspNetCore;
using Abp.Dependency;
using Abp.Domain.Uow;
using Abp.PlugIns;
using Castle.Windsor.MsDependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SalesVeeFunctionApp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

var host = new HostBuilder().ConfigureFunctionsWorkerDefaults().ConfigureServices(services=> {


    services.AddAbp<SalesVeeFunctionAppModule>();
    var _bootstrapper = AbpBootstrapper.Create<SalesVeeFunctionAppModule>();
    services.AddSingleton(_bootstrapper);
    _bootstrapper.Initialize();
    



})
    .Build();
host.Run();

So i can get my repositories in my azure function like this:

            var _bootstrapper = AbpBootstrapper.Create<SalesVeeFunctionAppModule>();
            using (var unit = _bootstrapper.IocManager.Resolve<IUnitOfWorkManager>().Begin())
            {
                var tester = _bootstrapper.IocManager.Resolve<IRepository<Customer>>();
                var d = tester.GetAllList();
            }

Sure,

This is the full stack trace.

Exception: System.InvalidOperationException: Unable to resolve service for type 'Abp.Domain.Repositories.IRepository`1[Bookenta.Customers.Customer]' while attempting to activate 'SalesVeeFunctionApp.Upload'. [2024-02-09T10:54:38.733Z] at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) [2024-02-09T10:54:38.736Z] at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) [2024-02-09T10:54:38.738Z] at Microsoft.Azure.Functions.Worker.DefaultFunctionActivator.CreateInstance(Type instanceType, FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionActivator.cs:line 23 [2024-02-09T10:54:38.739Z] at SalesVeeFunctionApp.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\Yasmin.alaa\source\repos\App\aspnet-core\SalesVeeFunctionApp\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 51 [2024-02-09T10:54:38.740Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13 [2024-02-09T10:54:38.741Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 Stack: at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) [2024-02-09T10:54:38.744Z] at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) [2024-02-09T10:54:38.756Z] at Microsoft.Azure.Functions.Worker.DefaultFunctionActivator.CreateInstance(Type instanceType, FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionActivator.cs:line 23 [2024-02-09T10:54:38.758Z] at SalesVeeFunctionApp.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\Yasmin.alaa\source\repos\App\aspnet-core\SalesVeeFunctionApp\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 51 [2024-02-09T10:54:38.760Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13 [2024-02-09T10:54:38.763Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77. [2024-02-09T10:54:38.779Z] Executed 'Functions.Upload' (Failed, Id=9b27b8c0-5052-499e-bb71-22af063dd83c, Duration=282ms) [2024-02-09T10:54:38.781Z] System.Private.CoreLib: Exception while executing function: Functions.Upload. System.Private.CoreLib: Result: Failure

Should my program.cs be like this ?

public class Program { private static void Main(string[] args) { var host = new HostBuilder(). ConfigureFunctionsWorkerDefaults().Build(); using (var bootstrapper = AbpBootstrapper.Create<SalesVeeFunctionAppModule>()) { bootstrapper.Initialize(); //Getting a Tester object from DI and running it using (var tester = bootstrapper.IocManager.ResolveAsDisposable<IRepository<Customer>>()) { tester.Object.Count(); } //Disposes tester and all it's dependencies } host.Run(); } }

Thanks for the reply, I did as you mentioned and following is my module:

using Abp.Modules; using Abp.Reflection.Extensions; using Bookenta.EntityFrameworkCore; namespace SalesVeeFunctionApp { [DependsOn( typeof(BookentaEntityFrameworkCoreModule) )] public class SalesVeeFunctionAppModule : AbpModule { public override void Initialize() { IocManager.RegisterAssemblyByConvention(typeof(SalesVeeFunctionAppModule).GetAssembly());

    }

    
}

}

When i try to inject my IRepository in my azure function constructor i got the following error

Did i miss something? Thanks.

We will try all the above and let you know, if something does not go as expected.

But we have a very important question related to above somehow. In our project, when a user is created at a Tenant, we automatiically create for him another user at host and link both using Linked Accounts. What we want now is: When user logs on the host application (using his host-based user), he should be able to click on a link that would open a new window in which the tenant application would open with him automatically logged in with his linked tenant user without entering username or password. And we do not want him logged out of the host application. And also vice versa; When user logs on the tenant application (using his tenant-based user), he should be able to click on a link that would open a new window in which the host appliacation would open with him automatically logged in with his linked host user without entering username or password. And we do not want him logged out of the host application. It is as-if each application is an external authenticator for the other. But when it externallly authenticates, user remains logged in on both applications (one as host-user and the other as tenant-user)

Please note that host application is an MVC app while the tenant application is an Angular app.

Maybe the tokens would be different with different JwtBeareer keys. But the problem is in the AbpTenant cookie. It always has the same name. So it would be shared.

As for having the apps on different subdomains or domains, this is what we are trying to do currently but DNS changes are taking 24-72 hours to propagate. The challenge is in debugging and development from visual studio. We cannot debug on IISExpress as it depends on having a different port per application. Any suggestions for debugging? IIS for debugging would work but it requires a tedious process with every run. Any easier options for debugging?

Having this said, how can we make the Angular app work on a subdomain or IP without a port number? How to set this up in angular application. It currently runs on localhost:4200

Actually, we need your help to tell us how to achieve below: We want to have the below apps with the below subdomains:

  1. API i.e. swagger and host app on api.domain.com
  2. Admin i.e the main app which is an angular app on admin.domain.com. It supports tenants.
  3. GlobalPortal i.e. a portal that gets some data from all tenants for all external customers on domain.com itself without subdomain. It must be host based only without tenants
  4. TenantPortal i.e. a portal per tenant that gets data for external customers of each tenant. This would be on subdomain portal.domain.com

Please note that we support tenants in some of the above subdomains/apps. So how to support {tenancy_name} in subdomains? Let us say there is a tenancy name "XYZ", so we should have below subdomains:

  • api.domain.com
  • xyz.admin.domain.com
  • admin.domain.com itself of course for us a super administrators
  • domain.com. This is host based. Never can have tenants -> How to fix tenantId = null all over the whole app?
  • xyz.TenantPortal.domain.com. This is tenant based. Must have tenants always

Changing Jwt Bearer Secret Key had no difference.

I believe authentication is shared because cookies are shared. Cookies are not aware of port. On the other hand, each application is running at a different port. Could I be right in this assumption? What would be the solution if that is the case?

Correction to the original description of the issue: Apps do not share the user, they are logged out once another application logs in or changes its tenant or switches to host.

Also there is a worthwhile notice: -Angular app does not get affected whatever happens in the MVC app or in swagger. But it affects the other apps i.e. whenever I log out of angular app or change user in Angular, the other apps are logged out. -As for the MVC app and Swagger, once any of other applications (angular, MVC, swagger) changes the user or logs out, it is logged out.

Showing 1 to 6 of 6 entries