Base solution for your next web application
Open Closed

Interceptors on Core #5555


User avatar
0
ivanosw1 created

Hi, I'm implementing a new interceptor on Core version of Abp to make a different kind of log. Initially it didn't work but I've read that for Core the method must be virtual. But I've also read in this post [https://forum.aspnetboilerplate.com/viewtopic.php?f=5&t=11098&p=28564&hilit=interceptors#p28564]) that you don't use interceptor. So, to stay in sync, how do you log every application service methods on Core ?

Thank you


18 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    Similar to the AbpAuthorize mentioned in the post your provided.

    Abp does the same thing for auditing as well. Using native filter available in Asp.Net Core Mvc , AbpAuditActionFilter works without Interceptor

    See <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.AspNetCore/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs">https://github.com/aspnetboilerplate/as ... nFilter.cs</a>

    However, abp still has auditing function implemented using IInterceptor.

    See <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp/Auditing/AuditingInterceptor.cs">https://github.com/aspnetboilerplate/as ... rceptor.cs</a>

  • User Avatar
    0
    ivanosw1 created

    Thank you. But what I don't understand is that abpcore auditing intereceptor catch all my application service methods, but if I do the same thing, I cant catch only methods that are virtual.

    Where is the magic ?

  • User Avatar
    0
    aaron created
    Support Team

    Filters in ASP.NET Core allow you to run code before or after specific stages in the request processing pipeline. Interceptors allow you to intercept even non-Controller methods, but rely on the power of Castle DynamicProxy.

    ABP defines several pre-built filters for ASP.NET Core: https://aspnetboilerplate.com/Pages/Documents/AspNet-Core#filters

  • User Avatar
    0
    ivanosw1 created

    Thank you @aaron.

    I think that in this case the filters in Core are the best option. So I've created my filter to log some particular methods, but how can I add my filters to abp core filters? Note that I'm developing a module (folder plugins)

  • User Avatar
    0
    ryancyq created
    Support Team

    You can register your filters with MvcOptions.Filters

    See <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/e0ded5d8702f389aa1f5947d3446f16aec845287/src/Abp.AspNetCore/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs#L28-L36">https://github.com/aspnetboilerplate/as ... cs#L28-L36</a>

    Looking at similar issue at <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/3302">https://github.com/aspnetboilerplate/as ... ssues/3302</a>

    Assemblies loading at <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/e0ded5d8702f389aa1f5947d3446f16aec845287/src/Abp/PlugIns/FolderPlugInSource.cs#L36-L52">https://github.com/aspnetboilerplate/as ... cs#L36-L52</a>

    You can try adding the following code snippets in StartUp.cs of your ..Web.Host or ..Web.Mvc. I have not fully tested out the code yet but it should be somewhere along the line.

    services.PostConfigure<MvcOptions>(options =>
    {
        foreach(var a in new FolderPlugInSource(@"Your Plugin Folder").GetAssemblies())
        {
            foreach (var type in a.GetTypes())
            {
                if (type is IFilterMetadata)
                {
                    options.Filters.AddService(type);
                }
            }
        }
    });
    
  • User Avatar
    0
    ivanosw1 created

    Thank you @ryancyq

    I'm sorry but I don't see any snippet of code suitable to add new filter outside of the abzero code, because in the plugin I've not access to services configuration like in startup with options.Filters.AddService(typeof(AbpAuthorizationFilter); or services.PostConfigure<MvcOptions>....

    I mean something like : IocManager.Instance.Resolve<Filters>().Add(typeof(GdprFilter)) in preInitialize step of module.

    The problem is how to add new filters in plugin module.

    Thanks

  • User Avatar
    0
    ryancyq created
    Support Team

    The code snippet is to add in to your main project.

    The purpose of it is to load all the filters that are declared in the plug-in module class library.

  • User Avatar
    0
    ivanosw1 created

    Yes but you have to modify the main source code and a we prefer don't touch the main project for many reasons, first of all the upgrade to new versions.

    So briefly, you say that is not possibile to add a filter from a plugin module without modify the main code, right ?

  • User Avatar
    0
    ryancyq created
    Support Team

    It's still possible to add in your filters within AbpModule loaded via plug-in.

    You can try to resolve MvcOption in your module PostInitialize(), and add your filters using _mvcOptions.Filters.AddService(type of(Your filter)), however this require further analysis and test if it works or not.

  • User Avatar
    0
    ivanosw1 created

    Hi, I've tried many ways but all fails :-) (No component for supporting the service xyz was found)

    On PostBuild event:

    IocManager.Resolve<MvcOptions>().Filters.Add(typeof(GdprAuditFilter)); // Error IocManager.Resolve<IServiceProvider>().GetService(typeof(IMvcBuilder)); // Error IocManager.Resolve<IServiceCollection>(); //Error

    Can you help me?

  • User Avatar
    0
    ryancyq created
    Support Team

    Please share the full error stack trace and code for your plug-in module

    Do you mean PostInitialize of AbpModule for PostBuild ? Or you are referring to Visual Studio PostBuild event.

  • User Avatar
    0
    ivanosw1 created

    I mean PostInitialize of AbpModule.

    using Abp.Modules;
    using Abp.Reflection.Extensions;
    using Microsoft.AspNetCore.Mvc;
    using Uno.Gdpr.Application.Filters;
    using Uno.Gdpr.Core;
    using Uno.Gdpr.EntityFramework;
    
    namespace Uno.Gdpr.Application
    {
        [DependsOn(typeof(GdprCoreModule), typeof(GdprEntityFrameworkModule))]
        public class GdrpApplicationModule : AbpModule
        {
    
    
            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(typeof(GdrpApplicationModule).GetAssembly());
            }
    
            public override void PostInitialize()
            {
                IocManager.Resolve<MvcOptions>().Filters.AddService(typeof(GdprAuditFilter));
            }
        }
    }
    
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using Abp.AspNetCore.Mvc.Extensions;
    using Abp.Auditing;
    using Abp.Dependency;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Uno.Gdpr.Application.Interceptors;
    using Uno.Gdpr.Core;
    using Uno.Gdpr.Core.WriteModel;
    
    namespace Uno.Gdpr.Application.Filters
    {
        public class GdprAuditFilter : IAsyncActionFilter, ITransientDependency
        {
            private readonly IAuditingHelper _auditingHelper;
            private readonly IGdprHelper _gdprHelper;
    
            public GdprAuditFilter(IAuditingHelper auditingHelper, IGdprHelper gdprHelper)
            {
                _auditingHelper = auditingHelper;
                _gdprHelper = gdprHelper;
            }
    
            public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
            {
                // do something
            }
                   
        }
    }
    
  • User Avatar
    0
    ivanosw1 created

    Hi, I'm in a black hole ? No ways to register filters on abp module?

  • User Avatar
    0
    alper created
    Support Team

    show what you've done.

  • User Avatar
    0
    ivanosw1 created

    I've tried many ways on PostBuildEvent:

    IocManager.Resolve<MvcOptions>().Filters.Add(typeof(GdprAuditFilter)); // Error IocManager.Resolve<MvcOptions>().Filters.AddService(typeof(GdprAuditFilter)); //Error IocManager.Resolve<IServiceProvider>().GetService(typeof(IMvcBuilder)); // Error IocManager.Resolve<IServiceCollection>(); //Error

  • User Avatar
    0
    ismcagdas created
    Support Team

    Have you tried something like this;

    services.Configure<MvcOptions>(options =>
    {
    	options.Filters.AddService(typeof(GdprAuditFilter), order: 1);
    });
    
  • User Avatar
    0
    ivanosw1 created

    @ismcagdas, please, bear with me but I'm in a module plugin and I haven't access to services configurations. Sure, if I could change the aspnetboilerplate code it will work, but I can't.

    I'm on a module plugin.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @ivanosw1, sorry. Could you try something like below;

    1. In the Initialize method of your plugin module,
    IocManager.IocContainer.Register(
    	Component.For<IConfigureOptions<MvcOptions>>().Instance(new MyTestMvcConfigureOptions()).LifestyleSingleton()
    );
    
    1. Other classes,
    public class MyTestMvcConfigureOptions : IConfigureOptions<MvcOptions>
    {
    	public void Configure(MvcOptions options)
    	{
    		options.Filters.Add(new GdprAuditFilter());
    	}
    }
    
    public class GdprAuditFilter : IAsyncActionFilter
    {
    	public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    	{
    		throw new NotImplementedException();
    	}
    }