Base solution for your next web application

Activities of "bvz"

Currently, if I create a class that implements IApplicationService, or EfRepositoryBase, a UnitOfWork is created automatically. So if my ApplicationService gets a repository injected directly, the UnitOfWork created in the application service is used in the repository as well.

I want to create a layer between the repository and application service, called the manager layer.

But if I inject like this:

repository -> manager -> application service,

Repository is no longer injected into application service directly, and unit of work does not reach the repository through the manager.

So my question is, how can I get my manager to use the unit of work created in the application service, so that it is in turn used in the repository injected into the manager as well?

Putting [UnitOfWork] on the method inside the manager does the trick, as well as doing this: using (var uow = _unitOfWorkManager.Begin())

But I dont have to do this on every repository or application service method, so how can I achieve the same thing in the manager so that the same unit of work is shared across all three layers?

Thank you.

I am writing unit tests for Abp, and I have a class that inherits from Abp.TestBase.AbpIntegratedTestBase.

When I run this code:

var current = LocalIocManager.IocContainer.Resolve<IAbpSession>();

It resolves to a session of type:

Abp.TestBase.Runtime.Session.TestAbpSession

I did not register this in Castle, so I am guessing that AbpIntegratedTestBase is doing this registration. How can I override this with my own session for testing purposes, so that I can set the logged in user Id for testing?

Thank you for your time and effort!

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.

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?

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?

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?

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.

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?

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].

Showing 1 to 9 of 9 entries