Base solution for your next web application
Open Closed

Return a 404 page for tenant not found #9425


User avatar
0
compassinformatics17 created

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.


3 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    hi

    Can you share your full code?

    maybe you can throw a custom exception and catch it in an asp net core middleware. Then you can return a page or redirect a page in middleware.

  • User Avatar
    0
    compassinformatics17 created

    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;
            }
        }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Thanks @compassinformatics17 for sharing your solution.