Base solution for your next web application

Activities of "alharethi"

  • What is your product version? v8.7
  • What is your product type (Angular or MVC)? MVC
  • What is product framework type (.net framework or .net core)? .NET Core

If issue is about UI

  • Which theme are you using? default
  • What are the theme settings? defatul

I have changed the registration process to:

  1. Register with name, email, passwod & phone. This form is posting to a PreRegistration action method (which does not have view, just validating email and sending SMS code)
  2. Inside PreRegistration action, if there are no validation errors and SMS is sent out successfully, it RedirectToAction("ValidateSmsCode"). This ValidateSmsCode view is only supporting HttpGet
  3. If there are PreRegistration errors, I redirect the user to the initial registration page, however the URL mysteriously shows /PreRegistration;
  4. Once the user lands on ValidateSmsCode view, there is a form to validate the SMS which posts to the final Register action (existing ABP Register action).
  5. Once the user enters the SMS code, If the SMS code is wrong or has expired, I am returning the user to the ValidateSmsCode view.telling him the error
  6. If there are no errors, I register the user and the user should be taken to the final RegisterResult view

I have few issues:

  1. In step #3 above, when I say return RegisterView(model);, the URL remains on /PreRegistration.
  2. In step #5 above, if the SMS code is invalid, I am trying to take the user back to the ValidateSmsCode to enter the code again; so when I call return View(nameof(ValidateSmsCode));, I get the popup in Arabic ( I have localized it) that says error details were not sent from server
  3. In step #6 above, if everyone is going well; I am finally taking the user to the registartion result page; however I receive the same error as above error details were not sent from server

` [Route("[controller]/register-as-student")] public async Task RegisterAsStudent(string returnUrl = "", string ss = "")

{ return RegisterView(new RegisterViewModel { PasswordComplexitySetting = await _passwordComplexitySettingStore.GetSettingsAsync(), ReturnUrl = returnUrl, SingleSignIn = ss, IsTeacher = false }); }

    [Route("[controller]/register-as-teacher")]
    public async Task<ActionResult> RegisterAsTeacher(string returnUrl = "", string ss = "")
    {
        return RegisterView(new RegisterViewModel
        {
            PasswordComplexitySetting = await _passwordComplexitySettingStore.GetSettingsAsync(),
            ReturnUrl = returnUrl,
            SingleSignIn = ss,
            IsTeacher = true
        });
    }

    private ActionResult RegisterView(RegisterViewModel model)
    {
        CheckSelfRegistrationIsEnabled();

        ViewBag.UseCaptcha = !model.IsExternalLogin && UseCaptchaOnRegistration();

        return View(model.IsTeacher ? "RegisterAsTeacher" : "RegisterAsStudent", model);
    }

    [HttpPost]
    public async Task<ActionResult> PreRegistration(RegisterViewModel model)
    {
        var errorMessage = string.Empty;

        // validate reCaptcha
        if (!model.IsExternalLogin && UseCaptchaOnRegistration())
        {
            try
            {
                await _recaptchaValidator.ValidateAsync(HttpContext.Request.Form[RecaptchaValidator.RecaptchaResponseKey]);
            }
            catch (Exception e)
            {
                errorMessage = e.Message;
            }
        }

        if (string.IsNullOrEmpty(errorMessage))
        {
            var user = await _userManager.FindByEmailAsync(model.EmailAddress);
            if (user != null)
            {
                errorMessage = "تم التسجيل بهذا الإيميل سابقا, الرجاء التسجيل بحساب آخر.";
            }
            else
            {
                var code = "123456"; // RandomHelper.GetRandom(100000, 999999).ToString();

                HttpContext.Session.Set<string>(SMS_SESSION_KEY, code);
                HttpContext.Session.Set<RegisterViewModel>(REGISTRATION_SESSION_KEY, model);

                //await _smsSender.SendAsync(model.FullPhoneNumber, L("SmsVerificationMessage", code));
            }
        }

        if (!string.IsNullOrEmpty(errorMessage))
        {
            ViewBag.ErrorMessage = errorMessage;
            model.PasswordComplexitySetting = await _passwordComplexitySettingStore.GetSettingsAsync();
            return RegisterView(model);
        } 

        return RedirectToAction("ValidateSmsCode");
    }

    [Route("[controller]/verify-phone")]
    public ActionResult ValidateSmsCode()
    {
        var smsCode = HttpContext.Session.Get<string>(SMS_SESSION_KEY);
        var registerViewModel = HttpContext.Session.Get<RegisterViewModel>(REGISTRATION_SESSION_KEY);

        if (smsCode == null || registerViewModel == null)
        {
            TempData["ErrorMessage"] = L("VerifySmsMessageNotFoundErrorMessage");
        }

        ViewBag.SmsVerificationMessage = !string.IsNullOrEmpty(smsCode) ? "تم إرسال رمز التفعيل إلى رقم هاتفك بنجاح!" : null;

        return View();
    }

    [HttpPost]
    [UnitOfWork(IsolationLevel.ReadUncommitted)]
    public async Task<ActionResult> Register(VerifyRegistrationSecurityCodeViewModel securityModel)
    {
        var smsCode = HttpContext.Session.Get<string>(SMS_SESSION_KEY);
        var model = HttpContext.Session.Get<RegisterViewModel>(REGISTRATION_SESSION_KEY);

        try
        {
            var errorMessage = string.Empty;
            if (smsCode == null || model == null)
            {
                errorMessage = L("VerifySmsMessageNotFoundErrorMessage");
            }

            if (securityModel.Code != smsCode)
            {
                errorMessage = L("WrongSmsVerificationCode");
            }

            if (!string.IsNullOrEmpty(errorMessage))
            {
                TempData["ErrorMessage"] = errorMessage;
                return View(nameof(ValidateSmsCode));
            }

            ExternalLoginInfo externalLoginInfo = null;
            if (model.IsExternalLogin)
            {
                externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync();
                if (externalLoginInfo == null)
                {
                    throw new Exception("Can not external login!");
                }

                using (var providerManager = _externalLoginInfoManagerFactory.GetExternalLoginInfoManager(externalLoginInfo.LoginProvider))
                {
                    model.UserName = providerManager.Object.GetUserNameFromClaims(externalLoginInfo.Principal.Claims.ToList());
                }

                model.Password = await _userManager.CreateRandomPassword();
            }
            else
            {
                if (model.EmailAddress.IsNullOrEmpty() || model.Password.IsNullOrEmpty())
                {
                    throw new UserFriendlyException(L("FormIsNotValidMessage"));
                }
            }

            //set UserName to EmailAddress
            model.UserName = model.EmailAddress;

            var user = await _userRegistrationManager.RegisterAsync(
                model.Name,
                model.Surname,
                model.EmailAddress,
                model.UserName,
                model.Password,
                false,
                _appUrlService.CreateEmailActivationUrlFormat(AbpSession.TenantId),
                model.FullPhoneNumber,
                model.IsTeacher
            );

            //Getting tenant-specific settings
            var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin);

            if (model.IsExternalLogin)
            {
                Debug.Assert(externalLoginInfo != null);

                if (string.Equals(externalLoginInfo.Principal.FindFirstValue(ClaimTypes.Email), model.EmailAddress, StringComparison.OrdinalIgnoreCase))
                {
                    user.IsEmailConfirmed = true;
                }

                user.Logins = new List<UserLogin>
                {
                    new UserLogin
                    {
                        LoginProvider = externalLoginInfo.LoginProvider,
                        ProviderKey = externalLoginInfo.ProviderKey,
                        TenantId = user.TenantId
                    }
                };
            }

            await _unitOfWorkManager.Current.SaveChangesAsync();

            Debug.Assert(user.TenantId != null);

            var tenant = await _tenantManager.GetByIdAsync(user.TenantId.Value);

            //Directly login if possible
            if (user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin))
            {
                AbpLoginResult<Tenant, User> loginResult;
                if (externalLoginInfo != null)
                {
                    loginResult = await _logInManager.LoginAsync(externalLoginInfo, tenant.TenancyName);
                }
                else
                {
                    loginResult = await GetLoginResultAsync(user.UserName, model.Password, tenant.TenancyName);
                }

                if (loginResult.Result == AbpLoginResultType.Success)
                {
                    await _signInManager.SignInAsync(loginResult.Identity, false);
                    if (!string.IsNullOrEmpty(model.SingleSignIn) && model.SingleSignIn.Equals("true", StringComparison.OrdinalIgnoreCase) && loginResult.Result == AbpLoginResultType.Success)
                    {
                        var returnUrl = NormalizeReturnUrl(model.ReturnUrl);
                        loginResult.User.SetSignInToken();
                        returnUrl = AddSingleSignInParametersToReturnUrl(returnUrl, loginResult.User.SignInToken, loginResult.User.Id, loginResult.User.TenantId);
                        return Redirect(returnUrl);
                    }

                    return Redirect(GetAppHomeUrl());
                }

                Logger.Warn("New registered user could not be login. This should not be normally. login result: " + loginResult.Result);
            }

            return View("RegisterResult", new RegisterResultViewModel
            {
                TenancyName = tenant.TenancyName,
                NameAndSurname = user.Name + " " + user.Surname,
                UserName = user.UserName,
                EmailAddress = user.EmailAddress,
                IsActive = user.IsActive,
                IsEmailConfirmationRequired = isEmailConfirmationRequiredForLogin
            });
        }
        catch (UserFriendlyException ex)
        {
            ViewBag.UseCaptcha = !model.IsExternalLogin && UseCaptchaOnRegistration();
            ViewBag.ErrorMessage = ex.Message;

            model.PasswordComplexitySetting = await _passwordComplexitySettingStore.GetSettingsAsync();

            return View(model.IsTeacher ? "RegisterAsTeacher" : "RegisterAsStudent", model);
        }
    }

`

Hello, Another issue with the latest upgrade. I am seeing a weird issue with RTL. I literally changed the connection string to a new DB after performing migration and this is what I am getting:

Honestly, I am not sure if you guys have thorough testing once you release a product. I have wasted 6 hours upgrading and manually merging and now I don't want to even use the latest upgrade.

Can someone please look into this further? I would expect the menus to be on the right, and the text to be right-aligned as well as in this screen shot from my work on a previous version v8.7:

Hello, I upgraded my project to the latest version from v8.7 and I ran into this issue below.

To make sure I did not do anything wron with my merge, I started fresh with the latest downloaded:

  1. Changed connection string in Web.Mvc project
  2. Ran migration
  3. Yarn/NPM commands to prepare solution
  4. Built the solution
  5. Ran the solution: no build errors. All 15 projects for Web.sln ran without issues.
  6. Getting stuck with the exception below.

An error occurred while starting the application. ComponentNotFoundException: No component for supporting the service HealthChecks.UI.Core.Data.HealthChecksDb was found Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, Arguments arguments, IReleasePolicy policy, bool ignoreParentContext)

ComponentNotFoundException: No component for supporting the service HealthChecks.UI.Core.Data.HealthChecksDb was found Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, Arguments arguments, IReleasePolicy policy, bool ignoreParentContext) Castle.MicroKernel.DefaultKernel.Resolve(Type service, Arguments arguments) Castle.Windsor.WindsorContainer.Resolve(Type service) Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.ResolveInstanceOrNull(Type serviceType, bool isOptional) Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.GetServiceInternal(Type serviceType, bool isOptional) Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.GetRequiredService(Type serviceType) Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService<T>(IServiceProvider provider) HealthChecks.UI.Core.HostedService.UIInitializationHostedService.InitializeDatabase(IServiceProvider sp) HealthChecks.UI.Core.HostedService.UIInitializationHostedService.StartAsync(CancellationToken cancellationToken) Microsoft.AspNetCore.Hosting.HostedServiceExecutor.ExecuteAsync(Func<IHostedService, Task> callback, bool throwOnFirstFailure) Microsoft.AspNetCore.Hosting.WebHost.StartAsync(CancellationToken cancellationToken) Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, string startupMessage) Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, string startupMessage) Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token) Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host) LMS.Web.Startup.Program.Main(string[] args) in Program.cs + CreateWebHostBuilder(args).Build().Run();

Further details: Castle.MicroKernel.ComponentNotFoundException: No component for supporting the service HealthChecks.UI.Core.Data.HealthChecksDb was found at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, Arguments arguments, IReleasePolicy policy, Boolean ignoreParentContext) at Castle.MicroKernel.DefaultKernel.Resolve(Type service, Arguments arguments) at Castle.Windsor.WindsorContainer.Resolve(Type service) at Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.ResolveInstanceOrNull(Type serviceType, Boolean isOptional) at Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.GetServiceInternal(Type serviceType, Boolean isOptional) at Castle.Windsor.MsDependencyInjection.ScopedWindsorServiceProvider.GetRequiredService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at HealthChecks.UI.Core.HostedService.UIInitializationHostedService.InitializeDatabase(IServiceProvider sp) at HealthChecks.UI.Core.HostedService.UIInitializationHostedService.StartAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.HostedServiceExecutor.ExecuteAsync(Func`2 callback, Boolean throwOnFirstFailure) at Microsoft.AspNetCore.Hosting.WebHost.StartAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token) at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host) at LMS.Web.Startup.Program.Main(String[] args) in C:\Devel\LMS\src\LMS.Web.Mvc\Startup\Program.cs:line 12

Showing 1 to 3 of 3 entries