Use IServiceProvider via DI in filter

Gianni 26 Reputation points
2021-10-01T08:13:42.093+00:00

Good morning

I have a custom class that implement IExceptionFilter in web api Core projetc (3.1)
I need to inject IServiceProvider in "OnException" method. In Startup class, i register my ExceptionFilter

            services.AddMvc(options =>
            {
                options.Filters.Add(new MyExceptionFilter());
            });

I have try in startup class to use BuildServiceProvider for inject an IServiceProvider and pass it in my filter constructor, but is a bad way.
How can I do?

Thanks

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,140 questions
{count} vote

Accepted answer
  1. Zhi Lv - MSFT 32,006 Reputation points Microsoft Vendor
    2021-10-15T07:48:11.99+00:00

    Hi @Gianni ,

    My question is how can I inject or pass an IServiceProvider in my "MyExceptionFilter" class in "OnException" method for inject object from DI.

    Do you mean you want to call the service in the custom exception filter method? If that is the case, you can refer the following sample code to directly inject the service in the custom exception filter or use the IServiceProvider:

    Create a IDataRepository to return the test data:

    public interface IDataRepository  
    {  
        List<Student> GetStudents();  
    }  
    
    public class DataRepository : IDataRepository  
    {  
        public List<Student> GetStudents()  
        {  
            return new List<Student>()  
            {  
                new Student(){ ID=1, LastName="AA"},  
                new Student(){ ID=2, LastName="BB"},  
                new Student(){ ID=3, LastName="CC"},  
            };  
        }  
    }  
    

    The custom exception filter as below:

    public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter  
    {  
        //To call the service, we could use the following methods:  
        //directly inject the service  
        public IDataRepository dataRepository;  
        //via the IServiceProvider.  
        public IServiceProvider _provider;  
        public int Order { get; } = int.MaxValue - 10;  
        public HttpResponseExceptionFilter(IServiceProvider serviceProvider, IDataRepository repository)  
        {  
            _provider = serviceProvider;  
            dataRepository = repository;  
        }  
    
        public void OnActionExecuting(ActionExecutingContext context) { }  
    
        public void OnActionExecuted(ActionExecutedContext context)  
        {   
            //via the service  
            var data = dataRepository.GetStudents();  
            //via the service provider  
            //get the service  
            var provider = (IDataRepository)_provider.GetService(typeof(IDataRepository));  
            //get the data.  
            var data2 = provider.GetStudents();  
    
            if (context.Exception is HttpResponseException exception)  
            {  
                context.Result = new ObjectResult(exception.Value)  
                {  
                    StatusCode = exception.Status,  
                };  
                context.ExceptionHandled = true;  
            }  
        }  
    }  
    

    Then, configure the service and the custom exception filter in the ConfigureService method as below:

        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddScoped<IDataRepository, DataRepository>();  
    
            services.AddControllers(config => config.Filters.Add(typeof(HttpResponseExceptionFilter)));  
            ...  
         }  
    

    The result as below:

    140796-1.gif


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread

    Best regards,
    Dillion

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful