Base solution for your next web application

Activities of "mcmaestro"

First off, I want to say this framework has saved me hours of development time and I have only been using this for 3 weeks. I have ran into a little issue and I hope you guys can help me out. Most of my application is going to be using the entity framework for database information, however, there is a module that we are building that will work with MongoDB or DocumentsDB to store all the session information. I want to build a custom repository but I am confused as to how to set this up do I need to add a class to the solution and reference the IRepository interface and fill in the concrete methods for accessing the information in the no sql database. Should I build a separate dll entirely?

Thanks!

For some reason when I try to delete an entity object it will not actually delete from the database.

For Example here is my Application Service TemplateAppService, I have a method that called DeleteTemplate and after it runs successfully, I know in the database that the record is not actually delete.

I have even tried to run SaveChanges method manually.

Any help would be appreciated.

Thanks,

public class TemplateAppService : KameleonAppServiceBase, ITemplateAppService
    {
        private readonly IRepository<Template, long> _templateRepository;
        private readonly IRepository<TemplateStatus> _templateStatusRepository;
        private readonly IRepository<TemplateCategory> _templateCategoryRepository;
        private readonly ISvgCreativeAppService _svgCreativeAppService;

        public TemplateAppService(IRepository<Template, long> templateRepository, ISvgCreativeAppService svgCreativeAppService, IRepository<TemplateStatus> templateStatusRepository, IRepository<TemplateCategory> templateCategoryRepository)
        {
            _templateRepository = templateRepository;
            _svgCreativeAppService = svgCreativeAppService;
            _templateStatusRepository = templateStatusRepository;
            _templateCategoryRepository = templateCategoryRepository;
        }

        public async Task<long> CreateTemplate(TemplateInput input)
        {
            var template = new Template();

            input.MapTo(template);

           var id  =  await _templateRepository.InsertAndGetIdAsync(template);

          
               await _svgCreativeAppService.CreateSvgCreative(
                      new SvgCreativeInput
                      {
                          Name = template.Name,
                          TemplateId = id,
                          BaseProductId = input.BaseProductId
                      }
                  );

               await CurrentUnitOfWork.SaveChangesAsync();          

           return id;
        }

        public async Task UpdateTemplate(TemplateInput input)
        {
            var template = await _templateRepository.GetAsync(input.Id);

            if (template == null)
            {
                throw new UserFriendlyException("Product Service Not Found!");
            }

            input.MapTo(template);

            await _templateRepository.UpdateAsync(template);
        }

        public async Task DeleteTemplate(EntityRequestInput<long> input)
        {
            var template = await _templateRepository.GetAsync(input.Id);

            if (template == null)
            {
                throw new UserFriendlyException("Template not found!");
            }

            await _templateRepository.DeleteAsync(template);

            await CurrentUnitOfWork.SaveChangesAsync();
        }

        public async Task<int> CreateTemplateStatus(TemplateStatusInput input)
        {
            var templatestatus = new TemplateStatus();
            
            input.MapTo(templatestatus);

            return await _templateStatusRepository.InsertAndGetIdAsync(templatestatus);

          
        }

        public async Task UpdateTemplateStatus(TemplateStatusInput input)
        {
            var templatestatus = await _templateStatusRepository.GetAsync(input.Id);

            if (templatestatus == null)
            {
                throw new UserFriendlyException("Template Status Not Found!");
            }

            input.MapTo(templatestatus);

            await _templateStatusRepository.UpdateAsync(templatestatus);
        }

        public async Task DeleteTemplateStatus(EntityRequestInput input)
        {
            var templatestatus = await _templateStatusRepository.GetAsync(input.Id);

            if (templatestatus == null)
            {
                throw new UserFriendlyException("Template Status not found!");
            }

            await _templateStatusRepository.DeleteAsync(templatestatus);

            CurrentUnitOfWork.SaveChanges();
        }       
        
        public async Task<TemplateOutput> GetTemplate(EntityRequestInput<long> input)
        {
            var template = await _templateRepository.GetAsync(input.Id);

            if (template == null)
            {
                throw new UserFriendlyException("Template not found!");
            }

            var result = new TemplateOutput();

            template.MapTo(result);

            return result;            
        } 

        public async Task<int> CreateTemplateCategory(TemplateCategoryInput input)
        {
            var templatecategory = new TemplateCategory();

            input.MapTo(templatecategory);

            return await _templateCategoryRepository.InsertAndGetIdAsync(templatecategory);
        }

        public async Task UpdateTemplateCategory(TemplateCategoryInput input)
        {
            var templatecategory = await _templateCategoryRepository.GetAsync(input.Id);

            if (templatecategory == null)
            {
                throw new UserFriendlyException("Template Category Not Found!");
            }

            input.MapTo(templatecategory);

            await _templateCategoryRepository.UpdateAsync(templatecategory);
        }

        public async Task DeleteTemplateCategory(EntityRequestInput input)
        {
            var templatecategory = await _templateCategoryRepository.GetAsync(input.Id);

            if (templatecategory == null)
            {
                throw new UserFriendlyException("Template Category not found!");
            }          

            await _templateCategoryRepository.DeleteAsync(templatecategory);

            await CurrentUnitOfWork.SaveChangesAsync();
        }


        public async Task<TemplateListOutput> GetTemplates(TemplateListInput input)
        {
            var results = await _templateRepository.GetAll().WhereIf(!input.SearchedName.IsNullOrEmpty(), p => p.Name.Contains(input.SearchedName)).OrderBy(x => x.Name)
                            .Skip(input.SkipCount * input.MaxResultCount).Take(input.MaxResultCount).ToListAsync();



            return new TemplateListOutput { Templates = Mapper.Map<List<TemplateOutput>>(results) };
        }

        public async Task<TemplateStatusListOutput> GetTemplatesStatuses(TemplateStatusListInput input)
        {
            var results = await _templateStatusRepository.GetAll().WhereIf(!input.SearchedName.IsNullOrEmpty(), p => p.Name.Contains(input.SearchedName)).OrderBy(x=> x.Name)
                            .Skip(input.SkipCount * input.MaxResultCount).Take(input.MaxResultCount).ToListAsync();



            return new TemplateStatusListOutput { TemplateStatuses = Mapper.Map<List<TemplateStatusOutput>>(results) };
        }

        public async Task<TemplateCategoryListOutput> GetTemplateCategories(TemplateCategoryListInput input)
        {
            var results = await _templateCategoryRepository.GetAll().WhereIf(!input.SearchedName.IsNullOrEmpty(), p => p.Category.Name.Contains(input.SearchedName)).WhereIf(!input.TemplateIdFilter.HasValue, y=> y.TemplateId == input.TemplateIdFilter.Value).OrderBy(x => x.Id)
                            .Skip(input.SkipCount * input.MaxResultCount).Take(input.MaxResultCount).ToListAsync();



            return new TemplateCategoryListOutput { TemplateCategories = Mapper.Map<List<TemplateCategoryOutput>>(results) };
        }
    }

I figured out the issue. My Template entity was being referenced in other database tables but deleting entities with casade was disabled for this table. So the database was throwing an error but it was never making it to the fronted.

Thanks for your help.

Hello all,

We are developing multiple applications that are use the boilerplate but I would like for the user to be able to have one login and be able to login or use a service from a different applications.

Kind of like google login process for it's services.

Any help would be great!

Thanks,

Question

I may be missing something but I have a few long running processes that are failing to complete because the transaction is timing out.

I have tried to set the transaction timeout to an extremely large number but it always fails after ten minutes regardless.

Here is the error message I receive after letting the process run longer than ten minutes.

System.AggregateException

One or more errors occurred.

System.AggregateException: One or more errors occurred. ---> Hangfire.BackgroundJobClientException: Background job creation failed. See inner exception for details. ---> System.Transactions.TransactionException: The operation is not valid for the state of the transaction. ---> System.TimeoutException: Transaction Timeout
   --- End of inner exception stack trace ---
   at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction, Guid promoterType)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification)
   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
   at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
   at System.Data.ProviderBase.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Hangfire.SqlServer.SqlServerStorage.CreateAndOpenConnection()
   at Hangfire.SqlServer.SqlServerStorage.UseConnection[T](Func`2 func)
   at Hangfire.SqlServer.SqlServerConnection.CreateExpiredJob(Job job, IDictionary`2 parameters, DateTime createdAt, TimeSpan expireIn)
   at Hangfire.Client.CoreBackgroundJobFactory.Create(CreateContext context)
   at Hangfire.Client.BackgroundJobFactory.&lt;&gt;c__DisplayClass7_0.&lt;CreateWithFilters&gt;b__0()
   at Hangfire.Client.BackgroundJobFactory.InvokeClientFilter(IClientFilter filter, CreatingContext preContext, Func`1 continuation)
   at Hangfire.Client.BackgroundJobFactory.Create(CreateContext context)
   at Hangfire.BackgroundJobClient.Create(Job job, IState state)
   --- End of inner exception stack trace ---
   at Hangfire.BackgroundJobClient.Create(Job job, IState state)
   at Abp.Hangfire.HangfireBackgroundJobManager.EnqueueAsync[TJob,TArgs](TArgs args, BackgroundJobPriority priority, Nullable`1 delay)
   at NMI.SmartMarketBusiness.MarketServices.MarketServiceExportBackgroundJob.&lt;&gt;c__DisplayClass10_1.&lt;&lt;Execute&gt;b__3>d.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at NMI.SmartMarketBusiness.MarketServices.MarketServiceExportBackgroundJob.Execute(MarketServiceExportBackgroundJobArgs args)
---> (Inner Exception #0) Hangfire.BackgroundJobClientException: Background job creation failed. See inner exception for details. ---> System.Transactions.TransactionException: The operation is not valid for the state of the transaction. ---> System.TimeoutException: Transaction Timeout
   --- End of inner exception stack trace ---
   at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction, Guid promoterType)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification)
   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
   at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
   at System.Data.ProviderBase.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Hangfire.SqlServer.SqlServerStorage.CreateAndOpenConnection()
   at Hangfire.SqlServer.SqlServerStorage.UseConnection[T](Func`2 func)
   at Hangfire.SqlServer.SqlServerConnection.CreateExpiredJob(Job job, IDictionary`2 parameters, DateTime createdAt, TimeSpan expireIn)
   at Hangfire.Client.CoreBackgroundJobFactory.Create(CreateContext context)
   at Hangfire.Client.BackgroundJobFactory.<>c__DisplayClass7_0.<CreateWithFilters>b__0()
   at Hangfire.Client.BackgroundJobFactory.InvokeClientFilter(IClientFilter filter, CreatingContext preContext, Func`1 continuation)
   at Hangfire.Client.BackgroundJobFactory.Create(CreateContext context)
   at Hangfire.BackgroundJobClient.Create(Job job, IState state)
   --- End of inner exception stack trace ---
   at Hangfire.BackgroundJobClient.Create(Job job, IState state)
   at Abp.Hangfire.HangfireBackgroundJobManager.EnqueueAsync[TJob,TArgs](TArgs args, BackgroundJobPriority priority, Nullable`1 delay)
Answer

<cite>ismcagdas: </cite> Hi,

Does any of your jobs are accessing a different database ? If so it might be a MSDTC problem. MSDTC service must be up and running. If your SQL Server is on a different server, then MSDTC service must be up and running on both machines.

If not, does this happen randomly or is it always in this way ?

  1. It was at first but I removed all external database calls. It only references the default database.

  2. For this job it has always been this way. I get a large list of orders then I process each one against another set on the server. I wonder if it is because I don't make any database calls while the process is running. Kinda of like how some apps log you out after a few min. of inactivity.

  3. My App and Database are on two different servers and I think MSDTC is running. I will check on this though.

Thanks for you help. I was able to get around temporarily but disabling UOW and manually calling new UOWs when I needed access the database after the application timeout happens.

<cite>ismcagdas: </cite> Hi,

You can use token based authentication for your other apps. See <a class="postlink" href="https://aspnetzero.com/Documents/Development-Guide#token-based-authentication">https://aspnetzero.com/Documents/Develo ... entication</a>

I could but I still would need to have the user's account automatically set up in the other application if it does not exists. I read some articles on stackoverflow about how they handle this issues so I am going to try to follow up on that.

Thanks for your help.

Question

I need to extend the AbpSession to keep up with a value that I can use through out the system. We have an another level the user can fall into. (lets say a Company) so when the user logs in under a company I want to save that information in the AbpSessions so I can apply filters to based on that value.

Is there a way I can add that field to the ABPSession object?

Answer

We already use the Tenant information but a tenant could have multiple companies that a user could reference for different pages. So I would like to be able to set that information up in the Session then use dynamic filters to reference the CompanyId. But I am not sure how to add the property to the session.

Thanks!

Thanks @hikalkan and everyone else help on this.

I have decided the second option that you mentioned is good and I have made some great progress but I have ran into another issue. Locally when I have the two application running and I try to login to the second app. After the first app redirects back to the second app. The AbpSession information from the first app is referenced in the Second app which causes an error. How is that possible? When I go directly to the second app the page loads the data correctly. Is the Clams Identity unique per application or is that information shared?

Showing 1 to 10 of 13 entries