Base solution for your next web application

Activities of "carelearning"

Hello ABP Support,

  • What is your product version? 10.4.0.0
  • What is your product type (Angular or MVC)? MVC
  • What is product framework type (.net framework or .net core)? .net framework 4.6.1
  • What is ABP Framework version? 6.4.0-rc1

Following this guide, https://volosoft.com/blog/Migrating-from-ASP.NET-MVC-5.x-to-ASP.NET-Core; we ran into some issues while converting from ASP.NET MVC 5 to the SDK-style project format. After converting our EntityFramework project when running the Migrator tool, we received the following error message (Unable to update database... see screenshot below):

Unfortunately due to the size of the product we are unable to send you the full solution. Is there source code available for the final converted solution from the blog post article? Is there a newer guide that has updated details about the migration process?

Thank you for your time and effort.

Dear Support,

We are using the legacy .NET Framework 4.6.1 (MVC 5/Angular) version 6.1.1 with Single Deployment/Multiple Database

For our POST action in our AccountController for Login we want to currently limit authentication of users who have the role 'Administrator'.

Following the call to GetLoginResultAsync we have added this code:

    var isAdministrator = loginResult.Identity.Claims
        .Where(x => x.Type == ClaimTypes.Role)
        .Any(x => x.Value == Constants.Administrator);

    if (!isAdministrator)
        return Json(new AjaxResponse { Success = false, UnAuthorizedRequest = true, Error = new ErrorInfo(L("InvalidRole")) });

This works, however we noticed our Javascript side localization was missing. After investigating we discovered the call to http://localhost:5000/AbpScripts/GetScripts was failing with this exception:

    WARN 2021-01-13 11:37:58,042 [12 ] Abp.Logging.LogHelper - Abp.Authorization.AbpAuthorizationException: Current user did not login to the application!
    at Abp.Authorization.AuthorizationHelper.Authorize(IEnumerable`1 authorizeAttributes) 	 at Abp.Web.Mvc.Authorization.AbpMvcAuthorizeFilter.OnAuthorization(AuthorizationContext filterContext) 	Abp.Authorization.AbpAuthorizationException: Current user did not login to the application! 	 at Abp.Authorization.AuthorizationHelper.Authorize(IEnumerable`1 authorizeAttributes)
    at Abp.Web.Mvc.Authorization.AbpMvcAuthorizeFilter.OnAuthorization(AuthorizationContext filterContext)
    ERROR 2021-01-13 11:38:46,234 [15 ] Web.Mvc.Controllers.AbpScriptsController - There is no role with name: Administrator
    Abp.AbpException: There is no role with name: Administrator
    at Abp.Authorization.Roles.AbpRoleManager\`2.d\_\_59.MoveNext()
    \-\-\- End of stack trace from previous location where exception was thrown \-\-\-

In our AbpRoleManager class we overrode the GetRoleByNameAsync method with the following:

public override async Task<Role> GetRoleByNameAsync(string roleName)
{
    return await Task.FromResult(_roleRepository
        .GetAll()
        .SingleOrDefault(x => String.Equals(x.Name, roleName)));
}

All this works but we wanted to touch base and figure out why this was necessary.

Thanks!

Question

We use 9.3 MVC/Jquery with .net framework

We understand that data in the abpSettings table is loaded at start-up. Is there a way to programmatically reload the settings form this table? We have a use case where a setting would change and we don't want the whole site to go down so that setting can be reloaded / refreshed.

Thank you for your time and effort.

Hello Volosoft,

We have the need to have localization of error messages. For example, "TenantId is missing" or "ConnectionString is missing." To accomplish this we have added this to AbpZeroTemplate.xml: <text name="CustomNotFound">{0} is missing</text> That works great.

Then our code will return such errors like: var errormessage = L("CustomNotFound", nameof(tenantId)); or var errormessage = L("CustomNotFound", nameof(connectionId));

This also works great.

Then we go to test it. So we have a test to look for "TenantId is missing" or "ConnectionString is missing" like this

     [Fact]
    public async Task AddCoursesAsync_NullTenantId_ReturnsFailure()
    {
        const string ErrorMessage = "tenantId is missing.";
        var tenantId = null;
        var actual = await _sut.Validate(tenantId, _connectionString);

        actual.Error.ShouldBe(ErrorMessage);
    }
      [Fact]
    public async Task AddCoursesAsync_NullConnectionString_ReturnsFailure()
    {
        const string ErrorMessage = "connectionString is missing.";
        var connectionString = null;
        var actual = await _sut.Validate(_tenantId, connectionString);

        actual.Error.ShouldBe(ErrorMessage);
    }

Note that we are using: _sut.LocalizationManager = NullLocalizationManager.Instance; per this post: https://support.aspnetzero.com/QA/Questions/1836

So it will return the error of "CustomNotFound." In this case, we need it to be unique. It cannot be "CustomNotFound" for both cases. Is it possible to get back something like "CustomNotFound, tenantId" or something like that to make it unique? In this module alone we have 114 unit tests based on this. We would like to avoid creating a localization for each one.

Update after response from @ismcagdas: Thank you for your response. Since we are using the "L()" method, it appears that I would have to create my own LocalizationSource.GetString(name, args) this is in LocalizationSourceExtensions.cs. Do I create another version of LocalizationSourceExtensions as well? or can I create that in my own NullLocalizationSource.cs? Or is this a better way?

Thanks again for your help.

Dear Volosoft Representative,

Steps to reproduce:

  1. Clone latest AbpZero github
  2. Configure The Project
  3. Create sample Tenant demo
  4. Create one user jdoe for new Tenant demo
  5. Create new controller Test under MPA area.
  6. Create new Index view for Test controller.
  7. Create Hubs folder in root of Web project
  8. Create ManagementHub under Hubs folder. Code
  9. Login and navigate /mpa/test/index
  10. Check app_data\logs\logs.txt Expected messages are not appearing
ManagementHub.cs
namespace MyCompanyName.AbpZeroTemplate.Web.Hubs
{
    using Abp.Dependency;
    using Abp.Runtime.Session;
    using Castle.Core.Logging;
    using Microsoft.AspNet.SignalR;
    using Microsoft.AspNet.SignalR.Hubs;
    using System.Threading.Tasks;

    [HubName("management")]
    public class ManagementHub: Hub, ITransientDependency
    {
        public IAbpSession AbpSession { get; set; }
        public ILogger Logger { get; set; }

        public ManagementHub()
        {
            AbpSession = NullAbpSession.Instance;
            Logger = NullLogger.Instance;
        }

        public override Task OnConnected()
        {
            await base.OnConnected();
            Logger.Debug($"A client connected to ManagementHub: {Context.ConnectionId}.");
            return Task.FromResult(0);
        }

        public override Task OnDisconnected(bool stopCalled)
        {
            await base.OnDisconnected(stopCalled);
            Logger.Debug($"A client disconnected to ManagementHub: {Context.ConnectionId}.");
            return Task.FromResult(0);
        }
    }
}
TestController.cs
using System.Web.Mvc;

namespace MyCompanyName.AbpZeroTemplate.Web.Areas.Mpa.Controllers
{
    public class TestController : Controller
    {
        // GET: Mpa/Test
        public ActionResult Index()
        {
            return View("Index");
        }
    }
}
Index.cshtml
@{
    ViewBag.Title = "title";
}

<h2>Welcome to TEST</h2>

Hello Volosoft Representatives, After upgrading to Abp 5.1 we were able to get our project to run in Visual Studio. However, when we published to IIS we got the following error:

Which was from the following code block in Global.asax.cs:

        private void RestoreUserLanguage()
        {
            var settingManager = AbpBootstrapper.IocManager.Resolve<ISettingManager>();
            var defaultLanguage = settingManager.GetSettingValue(LocalizationSettingNames.DefaultLanguage);

            if (defaultLanguage.IsNullOrEmpty())
            {
                return;
            }

            try
            {
                CultureInfo.GetCultureInfo(defaultLanguage);
                Response.Cookies.Add(new HttpCookie("Abp.Localization.CultureName", defaultLanguage) { Expires = Clock.Now.AddYears(2) });
            }
            catch (CultureNotFoundException exception)
            {
                LogHelper.Logger.Warn(exception.Message, exception);
            }
        }
        

We were able to reproduce this without making any customizations other than changing the connection string by cloning from aspnet-zero on the latest dev branch, we ran update-database -verbose and then published to IIS.

Is there anyway to resolve this?

Hello Volosoft Representatives,

We are pulling the latest updates (ABP 5.1) into our project. This requires an update from EF 6.2.0 to EF 6.4.0. When we run update-database we get this error:

System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid object name 'dbo.AbpTenants'.
  

We are using the "Single deployment/hybrid databases" approach as explained here: https://aspnetboilerplate.com/Pages/Documents/Multi-Tenancy#single-deployment-hybrid-databases. Our tenant databases do not have an abptenants table. The schema migrates and then we get an error during seeding. How can we investigate this error? We commented out the seed method seen here . Any information would be appreciated.

Dear Abp Represenative,

We encountered an issue while upgrading Abp NuGet packages from 4.9.0 to 4.10.0.

We are using the "ASP.NET MVC 5.x, Web API and AngularJS 1.x based Single-Page Application (SPA) solution."

After calling SaveChangesAsync on the CurrentUnitOfWork we get a "Value cannot be null Parameter name: source" exception (please reference included screenshot).

Here is the stack trace:

at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
 at Abp.EntityHistory.EntityHistoryHelper.GetRelationshipChanges(DbEntityEntry entityEntry, EntityType entityType, EntitySet entitySet, ICollection`1 relationshipChanges, Boolean auditedPropertiesOnly)
 at Abp.EntityHistory.EntityHistoryHelper.CreateEntityChangeSet(DbContext context)
 at Abp.Zero.EntityFramework.AbpZeroCommonDbContext`2.<SaveChangesAsync>d__104.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at Abp.EntityFramework.Uow.EfUnitOfWork.<SaveChangesInDbContextAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at Abp.EntityFramework.Uow.EfUnitOfWork.<SaveChangesAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
 at MyCompanyName.AbpZeroTemplate.Enrollment.EnrollmentAppService.<AddUserAsync>d__63.MoveNext() in c:\projects\port\src\careLearning\MyCompanyName.AbpZeroTemplate.Application\Enrollment\EnrollmentAppService.cs:line 934

Our work around is to disable the EntityHistory feature outlined here https://aspnetboilerplate.com/Pages/Documents/Entity-History.

This is a FYI for anyone else who may experience the issue.

Dear Support,

We are using the legacy MVC 5 version. In the Account controller and Login action we would like to run a SQL query (ClearUserLocksAsync) against a custom entity when an user logins in. However this returns the "The user could not login" error. We can wrap it in Try/Catch and ignore the exception. But we would like to explore if there is a better alternative.

Account->Login
      [HttpPost]
      [UnitOfWork]
      public virtual async Task&lt;JsonResult&gt; Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "")
      {
          // ... unmodified
          await UnitOfWorkManager.Current.SaveChangesAsync();

          // Custom call
          await _accessAppService.ClearUserLocksAsync(loginResult.User.Id);

          return Json(new AjaxResponse { TargetUrl = returnUrl });
      }
    }
    

AccessService->ClearUserLocksAsync

     public async Task ClearUserLocksAsync(long id)
    {
        var userLocks = await _lockRepository
            .GetAll()
            .Where(x => x.UserId == id)
            .ToListAsync();

        foreach (var userLock in userLocks)
            await _lockRepository.DeleteAsync(userLock);
    }
    

Error

Current user did not login to the application!

Stack Trace

Abp.Authorization.AbpAuthorizationException: Current user did not login to the application! at Abp.Authorization.AuthorizationHelper.<AuthorizeAsync>d__15.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.AuthorizationHelper.<CheckPermissions>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.AuthorizationHelper.<AuthorizeAsync>d__16.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task) at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task) at Nito.AsyncEx.AsyncContext.Run(Func`1 action) at Abp.Authorization.AuthorizationHelperExtensions.Authorize(IAuthorizationHelper authorizationHelper, MethodInfo methodInfo, Type type) at Abp.Authorization.AuthorizationInterceptor.Intercept(IInvocation invocation) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Abp.Auditing.AuditingInterceptor.PerformAsyncAuditing(IInvocation invocation, AuditInfo auditInfo) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.Proxies.AccessAppServiceProxy.ClearUserLocksAsync(Int64 id) at MyCompanyName.AbpZeroTemplate.Web.Controllers.AccountController.

Hello,

We have a project with several hundred tenants. What advice would you give to allow us to separate the communication between tenants? Currently, we send a "lock" message and all users receive this message regardless of tenancy. Options might include:

  • Give each tenant a separate endpoint, aka hub
  • Use signalR's group feature and assign each tenant an unique group name

We also plan to put our webservers behind a load balancer. Looking at the documentation (here), Redis is how you scale-out. Therefore the solution we are looking for needs to scale too.

Thank you for your time.

Showing 1 to 10 of 43 entries