编程语言
首页 > 编程语言> > c# – 有没有办法创建一个ActionFilter,它在Action语句中包含Action的内容?

c# – 有没有办法创建一个ActionFilter,它在Action语句中包含Action的内容?

作者:互联网

我的场景:我的应用程序是一个Web Api 2应用程序,它使用业务逻辑和存储库层进行数据访问. Web应用程序使用ASP.NET Impersonation以访问网站的用户身份登录数据库(通过PKI进行身份验证).我有几个异步控制器方法.但是,当我等待数据访问方法时,数据库调用可能会在另一个线程上完成,然后该线程将以我的应用程序池的标识访问数据库,该数据库不允许连接到数据库.

示例控制器:

public class TestApiController : ApiController {
    private IBusinessLogicObject _myBlObject;

    public TestApiController(IBusinessLogicObject myBlObject){
        _myBlObject = myBlObject; //Populated through Unity
    }

    public async Task<int> CountMyJobs(string name){
        return await _myBlObject.CountMyJobsAsync(name);
    }
}

示例业务逻辑类:

public class BusinessLogicObject : IBusinessLogicObject
{
    private IGenericRepository<Job> _jobRepository;

    public BusinessLogicObject(IGenericRepository<Job> _jobRepository)
    {
        _jobRepository = jobRepository; //Populated with Unity
    }

    public Task<int> CountMyJobsAsync(string name)
    {
        using (WindowsIdentity.GetCurrent().Impersonate())
        {
            //JobRepository is effectively a DbSet<Job> and this call returns IQueryable<Job>
            return _jobRepository.Where(i => i.Name == name).CountAsync();
        }        
    }
}

如果我将using语句移动到控制器中(包含在await中),它可以正常工作.

问题似乎是因为await在模拟上下文之外,它没有模拟数据库调用(CountAsync()),我无法打开与数据库的连接.

问题:

有没有办法可以在我的控制器方法上编写ActionFilter或其他属性,以便方法本身(包含await调用)会自动包装在using语句中?

解决方法:

merpmerp的答案在多线程服务器中会出现问题.由于每个修饰方法只有一个ActionFilterAttribute实例,因此对同一方法的两个同时请求将导致覆盖usingVariable,并且最终只会处理一个.

您需要更进一步,将ImpersonationContext存储在请求上下文中的某个位置 – 例如在filterContext.Request.Properties中.

标签:c,asp-net-web-api,async-await,action-filter,impersonation
来源: https://codeday.me/bug/20190629/1322027.html