gpt4 book ai didi

c# - 带有异步 Ajax 请求的同步 ActionFilter

转载 作者:太空宇宙 更新时间:2023-11-03 12:24:54 25 4
gpt4 key购买 nike

当我尝试在页面加载时向具有相同 IActionFilter 属性的 2 个 MVC 操作发出 2 个异步 ajax 请求时遇到并发问题。

SimpleInjector注册如下

public static Container Initialize(IAppBuilder app)
{
var container = GetInitializeContainer(app);
RegisterGlobalFilters(GlobalFilters.Filters, container);
container.Verify();

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

return container;
}

private static Container GetInitializeContainer(IAppBuilder app)
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

container.RegisterSingleton(app);

RegisterCustomDependacies(container);

container.Register(() => new ApplicationDbContext(), Lifestyle.Scoped);

container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

//At the moment of verification, there is now HttpContext to check. So create a new owin context to check instead and get the authentication manager.
container.Register(() => AdvancedExtensions.IsVerifying(container) ? new OwinContext(new Dictionary<string, object>()).Authentication
: HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);

return container;
}

public static void RegisterGlobalFilters(GlobalFilterCollection filters, Container container)
{
//Originally had this but it was causing the same issues
//filters.Add(new AuthoriseActionFilter(container.GetInstance<ICacheManager>(),
// container.GetInstance<IUserManager>(),
// container.GetInstance<IAuthorisationManager>(),
// container.GetInstance<IClientManager>(),
// container.GetInstance<ICookieManager>(),
// container.GetInstance<IAuthenticator>()
// ));

container.Register<IActionFilter, AuthoriseActionFilter>(Lifestyle.Scoped);
filters.Add(container.GetInstance<IActionFilter>());
filters.Add(new HandleErrorAttribute());
}

下面是同步 ActionFilter 的 2 个 Action

[AuthoriseAction("Can_Access_Summary")]
public async Task<PartialViewResult> ReturnPots(int? dateID, string date) {}


[AuthoriseAction("Can_Access_Summary")]
public async Task<string> GetImportedDates() {}

当 ActionFilter 从数据库中请求一些信息时,就会出现问题。我收到以下错误。

There is already an open DataReader associated with this Connection which must be closed first.

这只会在每 4 次页面刷新时发生一次。

下面是我的 IActionFilter 的简化版本

public void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
var attribute = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthoriseAction), false).SingleOrDefault() as AuthoriseAction;
if (attribute != null)
{
var userID = _cookieManager.DecryptFormsAuthenticationCookie(filterContext.HttpContext);

if (userID == -1) { filterContext.Result = new Http401Result(); return; }

var user = _userManager.LoadByIDSync(userID);

var isAuthenticated = _authenticator.AuthenticateUserSync(user);

...
}
}

我可以通过使 1 个 ajax 请求同步来解决此问题,但这不是真正的解决方案。我也可以通过 1 个请求返回所有数据,但同样,这并不是真正正确的解决方案。

谢谢

最佳答案

你可以用一个简单的扩展方法解决这个问题:

internal static class SimpleInjectorMvcActionFilterExtensions
{
public static void AddFilter<TActionFilter>(
this GlobalFilterCollection filters, Container container)
where TActionFilter : class, IActionFilter
{
// Register instance in the container to allow this instance to be
// diagnosed.
container.Register<TActionFilter>(Lifestyle.Scoped);

// Add a proxy to the global filters that resolves the real instance
filters.Add(new ActionFilterProxy<TActionFilter>(container));
}

private sealed class ActionFilterProxy<TActionFilter> : IActionFilter
where TActionFilter : class, IActionFilter
{
private readonly Container container;
public ActionFilterProxy(Container container) { this.container = container; }
public void OnActionExecuting(ActionExecutingContext c)=> Get().OnActionExecuting(c);
public void OnActionExecuted(ActionExecutedContext c)=> Get().OnActionExecuted(c);
private TActionFilter Get() => container.GetInstance<TActionFilter>();
}
}

您可以按如下方式使用它:

public static void RegisterGlobalFilters(
GlobalFilterCollection filters, Container container)
{
// Call extension method
filters.AddFilter<AuthoriseActionFilter>(container);
filters.Add(new HandleErrorAttribute());
}

而不是添加 AuthoriseActionFilter到全局过滤器列表(单例列表),ActionFilterProxy<AuthoriseActionFilter> 的一个实例被添加。这个代理实例可以安全地用作单例,因为它会回调到 container 中。在每个请求上解决一个新的 AuthoriseActionFilter对于每个请求。

关于c# - 带有异步 Ajax 请求的同步 ActionFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45505479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com