Base solution for your next web application

Activities of "compassinformatics17"

Hi,

I have extended ASP.NET Zero .NET Framework template with an entity with a DbGeometry field. It was all compilable and working when running the application. However, I noticed that all unit tests are broken with the following error:

Message: Castle.MicroKernel.ComponentActivator.ComponentActivatorException : ComponentActivator: could not instantiate GISWebTech.Recruit.EntityFramework.RecruitDbContext ---- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. -------- System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.

See attachment for a full stack trace from one of the tests. It seems to be failing on instantiating DbContext. Any ideas how to resolve this? I checked the references and they seem to be fine.

Thanks, Pavel

Hi All,

I wonder if someone might help to shed some light on an issue which I have noticed. I am putting together a project in AspNetZero Core MVC & Jquery. All is working well except I encountered an issue with the Abp.AutoMapper.

In the documentation there are two AutoMapping methods mentioned:

"CustomDtoMapper.cs is used to create mapping from Person to PersonListDto. FullAuditedEntityDto is inherited to implement audit properties automatically. See application service and DTO documentations for more information. We are adding the following mappings."

And

"We use Abp.AutoMapper library that makes usage of AutoMapper simpler and declarative."

But the example given on the page https://docs.aspnetzero.com/en/aspnet-core-mvc/latest/Infrastructure-Core-Mvc-Dto-Mappings is no longer representative of what is in the codebase, that mapping is now done in CustomDtoMapper.cs.

configuration.CreateMap<Tenant, TenantListDto>();
configuration.CreateMap<TenantEditDto, Tenant>().ReverseMap();

My issue is that Abp.AutoMapper does not seem to work at all from Application.Shared project in any DTO's. For instance if I try to enter the example on the above page in TenantEditDto.cs the Tenant class cannot be resolved.

using System;
using System.ComponentModel.DataAnnotations;
using Abp.Application.Services.Dto;
using Abp.Auditing;
using Abp.AutoMapper;
using Abp.MultiTenancy;

namespace CompassCorejQueryDemo.MultiTenancy.Dto
{
    [AutoMap(typeof(Tenant))]  //Tenant cannot be resolved here. I have tried the same in many other existing DTO's and in my own ones, but all behave the same, the typeof(class) cannot be resolved.

I have checked and Abp.AutoMapper is still used in other models and in the GraphQL DTO's but not in Application.Shared. All DTO's in Application.Shared are now handled by AutoMapper in CustomDtoMapper.cs.

I cross checked with an Asp.Net Zero MVC5 project and it matches exactly with the exception that Abp.AutoMapper works as intended in the MVC5 project.

Is there a reason for this change or am I missing something obvious? Any advice is appreciated.

Regards, Barry.

After much googling, I managed to track this down to a reported issue on github. It seems its related to the new project structure which means items in the Core project are not accessible from Application.Shared.

https://github.com/aspnetboilerplate/aspnetboilerplate/issues/4620

I hope it helps someone and saves them some searching to track down the issue.

Regards, Barry.

Hi,

I am testing minification in ASPNetZero Core. I can run npm run create-bundles without issue but when I run npm run build, I get the error below.

The error seems to be with /view-resources/Areas/App/Views/Common/_KeyValueListManager.js. On line 113 it appears to not be able to handle the period.

[1/4] Resolving packages... success Already up-to-date. Done in 0.61s. [17:19:18] Using gulpfile D:\CompassCoreJqueryDemo\src\CompassCorejQueryDemo.Web.Mvc\gulpfile.js [17:19:18] Starting 'build'... [17:19:33] 'build' errored after 15 s [17:19:33] SyntaxError in plugin "gulp-uglify-es" Message: Unexpected token: punc (.) Details: filename: _KeyValueListManager.js line: 113 col: 36 pos: 4251 domainEmitter: [object Object] domainThrown: false

npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] build: yarn && gulp build npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] build script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Thanks, Barry.

Hi, Not specifically a development question but I received a response today to another question which I had asked. I needed to add my GitHub username to our listed GitHub members. I did this and it reported that I had been added successfully. However I did not reveive any email. I also checked current invitations via my GitHub account and I have not received any invitations to accept. Is there currently an issue with the invitations? Thanks, Barry.

OK great thanks for the assistance. Much appreciated.

Hi Guys, This one seems like it should be easy but I cannot seem to find any reference to it in the docs.

I have enabled sub-domain wildcard multi-tenancy and it works just fine as specifed in the docs.

But when it is enabled, how do I then log in as the host user? If I go to the root domain sitename.com, it just defaults to the default tenant. Is there a way to configure a url for the host such as admin.sitename.com?

Thanks, Barry.

Brilliant thanks and apologies for the late reply, was on other projects.

For anyone trying to do the same see the step by step below:

  1. Create a custom DomainTenantResolver. I have stored this in the root of the Web.Core project.
using System;
using System.Linq;
using Abp.Dependency;
using Abp.Extensions;
using Abp.MultiTenancy;
using Abp.Text;
using Abp.Web.MultiTenancy;
using Microsoft.AspNetCore.Http;

namespace MyProject.Web
{
    public class CustomDomainTenantResolveContributor : ITenantResolveContributor, ITransientDependency
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IWebMultiTenancyConfiguration _multiTenancyConfiguration;
        private readonly ITenantStore _tenantStore;

        public CustomDomainTenantResolveContributor(
            IHttpContextAccessor httpContextAccessor,
            IWebMultiTenancyConfiguration multiTenancyConfiguration,
            ITenantStore tenantStore)
        {
            _httpContextAccessor = httpContextAccessor;
            _multiTenancyConfiguration = multiTenancyConfiguration;
            _tenantStore = tenantStore;
        }

        public int? ResolveTenantId()
        {
            if (_multiTenancyConfiguration.DomainFormat.IsNullOrEmpty())
            {
                return null;
            }

            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext == null)
            {
                return null;
            }

            var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://").RemovePostFix("/");
            var domainFormat = _multiTenancyConfiguration.DomainFormat.RemovePreFix("http://", "https://").Split(':')[0].RemovePostFix("/");
            var result = new FormattedStringValueExtracter().Extract(hostName, domainFormat, true, '/');

            if (!result.IsMatch || !result.Matches.Any())
            {
                return null;
            }

            var tenancyName = result.Matches[0].Value;
            if (tenancyName.IsNullOrEmpty())
            {
                return null;
            }

            if (string.Equals(tenancyName, "www", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }

            // Allow the use of admin.domain.com as the host url.
            if (string.Equals(tenancyName, "admin", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }

            var tenantInfo = _tenantStore.Find(tenancyName);
            if (tenantInfo == null)
            {
                return null;
            }

            return tenantInfo.Id;
        }
    }
}
  1. Add your custom resolver to MyProjectWebCoreModule.cs in the Web.Core project.

     public override void PreInitialize()
     {
         ...previous code
    
         Configuration.MultiTenancy.Resolvers.Insert(0, typeof(CustomDomainTenantResolveContributor));
    
         ...any additional code
     }
    
  2. Finally set up sub-domain bindings and dns entries in your hosting config.

Thanks, Barry.

I have written a customised DomainTenantResolveContributor which works just fine. It allows me to access the host via admin.{domain}.com and my various sub-domain tenants. One thing is escaping me however. I would like to return a 404 page when a tenant is not found. This seems like it should be simple, but no matter what I try in the framework, I cannot seem to kill the request and return a 404 if the tenant is not found. I have tried multiple approaches all with the same result, they just result in being sent to the host login which is certainly not desirable.

            var tenantInfo = _tenantStore.Find(tenancyName);
            if (tenantInfo == null)
            {
                // No tenant found matching the given name, return 404.
                throw new EntityNotFoundException();
            }

I'd really appreciate any advice on how to kill the request and redirect to a 404 here. From my reading .NET core should auto handle these types of exceptions but that is not happening here.

Thanks, Barry.

I managed to get this to work, albeit in a bit of a manual way. I could not find any way to reliably abort the request and return a 404 page, so I have handled it with a redirect and it works well.

public class MyProjectDomainTenantResolveContributor : ITenantResolveContributor, ITransientDependency
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IWebMultiTenancyConfiguration _multiTenancyConfiguration;
        private readonly IRepository<Tenant> _tenantRepository;
        private readonly IConfigurationRoot _appConfiguration;

        public MyProjectDomainTenantResolveContributor(
            IHttpContextAccessor httpContextAccessor,
            IWebMultiTenancyConfiguration multiTenancyConfiguration,
            IRepository<Tenant> tenantRepository,
            IAppConfigurationAccessor appConfigurationAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
            _multiTenancyConfiguration = multiTenancyConfiguration;
            _tenantRepository = tenantRepository;
            _appConfiguration = appConfigurationAccessor.Configuration;
        }

        public int? ResolveTenantId()
        {
            if (_multiTenancyConfiguration.DomainFormat.IsNullOrEmpty())
            {
                return null;
            }

            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext == null)
            {
                return null;
            }

            var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://").RemovePostFix("/");
            var domainFormat = _multiTenancyConfiguration.DomainFormat.RemovePreFix("http://", "https://").Split(':')[0].RemovePostFix("/");
            var result = new FormattedStringValueExtracter().Extract(hostName, domainFormat, true, '/');

            if (!result.IsMatch || !result.Matches.Any())
            {
                // Allow local testing in iis express without redirecting.
                if (hostName == "localhost")
                {
                    return null;
                }

                // No tenant, force our default tenant.
                httpContext.Response.Redirect(_appConfiguration["App:MissingTenantUrl"]);
                return null;
            }

            var tenancyName = result.Matches[0].Value;
            if (tenancyName.IsNullOrEmpty() || string.Equals(tenancyName, "www", StringComparison.OrdinalIgnoreCase))
            {
                // Allow local testing in iis express without redirecting.
                if (hostName == "localhost")
                {
                    return null;
                }

                // No tenant, force our default tenant.
                httpContext.Response.Redirect(_appConfiguration["App:MissingTenantUrl"]);
                return null;
            }

            // Allow the use of admin.domain.com as the host url.
            if (string.Equals(tenancyName, "admin", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }

            // Check if a tenant with the given name exists.
            var tenant = _tenantRepository.FirstOrDefault(t => t.TenancyName == tenancyName);

            if (tenant == null)
            {
                // No tenant found matching the given name, return 404.
                httpContext.Response.StatusCode = 404;
                httpContext.Response.Redirect(_appConfiguration["App:MissingTenantUrl"] + "/Error?statusCode=404");
                return null;
            }

            // Return tenant id.
            return tenant.Id;
        }
    }
Showing 1 to 10 of 23 entries