Base solution for your next web application

Activities of "bvz"

Answer

I am not using Zero.

I have already added some roles with this:

public override void SetPermissions(IPermissionDefinitionContext context)
        {
            var admin = context.CreatePermission("Admin", new LocalizableString("Admin", MixTechConsts.LocalizationSourceName));
            var superadmin = context.CreatePermission("SuperAdmin", new LocalizableString("SuperAdmin", MixTechConsts.LocalizationSourceName));
            var user = context.CreatePermission("User", new LocalizableString("User", MixTechConsts.LocalizationSourceName));
            
        }

My question is, when I call the API, and I hit something decorated with this:

[AbpAuthorize("Admin")]

How does ABP know how which users have which roles?

How does ABP know if the currently logged in user has the Admin role or not, so that it can decide if the user has access to the REST API call or not?

I need information about the logged in user in the EntityFramework layer. I also need this information in the IPermissionChecker implementation.

I have read this page: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Abp-Session">http://www.aspnetboilerplate.com/Pages/ ... bp-Session</a>

And I have implemented the IAbpSession interface like so:

class AbpSession : IAbpSession
    {
        public long? UserId
        {
            get
            {
                //var userId = Thread.CurrentPrincipal.Identity.GetUserId();
                return null;
            }
        }

        public int? TenantId { get; private set; }
    }

The Thread.CurrentPrincipal.Identity.GetUserId() line (commented out above) always returns null. How can I get identity of the currently logged in user in the implementation of IAbpSession?

I am authenticating using FormsAuthentication.SetAuthCookie. This works, because the user can access something marked with [Authorise].

I have implemented the IPermissionChecker interface:

public class PermissionChecker : IPermissionChecker
    {
        public async Task<bool> IsGrantedAsync(string permissionName)
        {
            return true;
        }

        public async Task<bool> IsGrantedAsync(long userId, string permissionName)
        {
            return true;
        }
    }

I am always returning true for now, I just want to check if I am wiring everything up correctly.

I then register the type like so:

IocManager.Instance.IocContainer.Register(
                Component.For<IPermissionChecker>().ImplementedBy<PermissionChecker>().LifestyleTransient());

When I make a call from angular on the API to a REST action that has this attribute:

[AbpAuthorize("Admin")]

The frontend angular generates an error message stating that "No user is logged in."

But a user IS logged in.

Also, neither of the IsGrantedAsync methods on the IPermissionChecker implementation are hit ever, so the system is not even attempting to find out if the current user has the required permissions. The constructor for PermissionChecker is being called though.

Questions:

  1. Why am I getting an error stating that no user is logged in, when there is a user logged in?
  2. When an API call tries to access an AbpAuthorize marked REST action, the user should be taken to the log in pate. How is the log in url specified for the single page angular side?

Thank you for your reply.

So internally, whenever ABP wants to find out who is logged in (to show the correct menu items, or to send the id to the PermissionChecker etc), it will always use the UserID from the IAbpSession implemtation, which it will grab from the IoC?

When the ApplicationService implementations are exposed as a REST service, how is determined if they should be POST, PUT or GET etc?

Can I override this somehoe? If I want updates to be PUT, and inserts to be POST, how do I tell ABP to expose them the way I want to when generating the REST api?

Thank you.

POST works fine for now.

But how does it know how to make it GET and when to make it POST?

What is the best way that you would recoment calling stored procedures through the EntityFramework provider?

Currently I have added the following to the DbContext file:

public virtual int? spr_AddUser(Nullable<int> clientID, string username, string password, string name, string surname, string iDNumber, string email, Nullable<int> createdBy)
        {
            var clientIdPar = new SqlParameter("@ClientID", clientID);

            var usernamePar = new SqlParameter("Username", username);

            var passwordPar = new SqlParameter("Password", password);

            var namePar = new SqlParameter("Name", name);

            var surnamePar = new SqlParameter("Surname", surname);

            var idNumberPar = new SqlParameter("IDNumber", iDNumber);

            var emailPar = new SqlParameter("Email", email);

            var createdByPar = new SqlParameter("CreatedBy", createdBy);

            var retvalPar = new SqlParameter("@retval", SqlDbType.Int);
            retvalPar.Direction = ParameterDirection.Output;
            
            var parameters = new object[] { clientIdPar, usernamePar, passwordPar, namePar, surnamePar, idNumberPar, emailPar, createdByPar, retvalPar };

            this.Database.ExecuteSqlCommand(
                "exec @retval = spr_AddUser @ClientID,@UserName,@Password,@Name,@Surname,@IDNumber,@Email,@CreatedBy",
                parameters);
            return (int) retvalPar.Value;
        }

This works,but I am not sure if this is the best way to call stored procedures when using ABP.

Could someone who is more experienced with ABP point me in the right direction?

I have reat the Unit Of Work documentation page, however, I have a question.

Consider this code:

public EntUserUnit AddUserUnit(EntUserUnit userUnit)
        {            
            Context.UserUnits.Add(userUnit);
            return userUnit;
        }

        public List<EntUserUnit> AddUserUnits(List<EntUserUnit> userUnits)
        {
            return userUnits.Select(AddUserUnit).ToList();
        }

This code is in an Application Service. The documentation states that a transaction will be started when I call theAddUserUnits(List<EntUserUnit> userUnits) method. This method then repeatedly calls another method, also on the Application Service.

If I send a list with 10 objects, will they all be added in the same transaction? If any one of them fails, will they all be rolled back?

I am trying to use the ICreationAudited interface on the Entities.

The problem I am running into is that the tables I am mapping to use int as the column type, not long.

The error is:

The 'CreatorUserId' property on 'EntUser' could not be set to a 'System.Int32' value. You must set this property to a non-null value of type 'System.Int64'.

So I understand why this is happening, my question is if it is possible to overcome this problem?

Question

Normally, in an ASP.Net application, I would override Application_Error in Global.asax.cs.

However, when I throw an exception in one of my BaseApplicationService implementations to test:

throw new Exception("TEST!!!");

the code in Global.asax.cs is never hit.

So I now have the following:

public override void Initialize()
        {
            AutoMapperConfig.Configure();
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

            EventBus.Default.Register<AbpHandledExceptionData>(x => HandleException(x.Exception));
        }

        private void HandleException(Exception ex)
        {
            EntException exObj = ex.GetHttpExceptionObject();
        }

This works. However, I need the HttpRequest object, becuase I need to log Headers and Form values and UserAgents and all kinds of other goodies from the HttpRequest object. This is easy in the Global.asax.cs Application_Error, because HttpRequest is in scope there.

So I need to:

  1. Access the Request object where the exception was raised.
  2. Make sure exceptions handled by Asp.Net boilerplate internals still reach Global.asax.cs.

Please advise. Thank you for your time and effort.

Showing 1 to 10 of 13 entries