c# - 从 ASP.Net 调用异步函数

标签 c# asp.net async-await impersonation

在一个 ASP.Net 项目中,我最近将一些冗长的函数更改为异步。事实证明,这会导致一些无法解释的问题。

基本上,函数在使用 await 时可以正常工作,但必须从另一个异步函数调用它最终成为表单中的一个问题。 到目前为止,我将页面指令 Async 设置为 true 并使用 RegisterAsyncTask 启动对异步函数的调用。通话有效。但事实证明,当我启用异步页面指令时,用户上下文有时会发生变化。

为了模拟某些页面中所有代码的调用用户,我将类 System.Web.UI.Page 继承到 ImpersonatedPage。在我的类里面,我使用 OnLoad 来模拟调用用户。通过这种方式,我可以确定用户永远不会看到或做任何他/她已经可以访问的事情,并且审核日志会显示正确的用户。

当启用异步页面指令时,它仍然模拟用户。但是例如在单击按钮的代码中,用户上下文突然返回到应用程序池上下文。在 Page_Load 中,用户上下文是预期的调用用户。 是什么原因造成的,是否可以避免切换回应用程序池用户?

或者,我尝试删除异步页面指令,并使用 Task.Run 调用异步函数。然后用户上下文不会切换回来,而是 HttpContext.Current 为空,异步函数无法完成它的工作。

有没有其他方法可以在不启用异步页面指令的情况下从 ASP.Net 调用异步函数?

目标框架:4.6.1 AFAIK 没有启用怪癖

模拟页面类:

public class ImpersonatedPage : System.Web.UI.Page
{
    WindowsImpersonationContext m_wic = null;

    protected override void OnLoad(EventArgs e)
    {
        WindowsIdentity wi = (WindowsIdentity)System.Web.HttpContext.Current.User.Identity;
        m_wic = wi.Impersonate();
        HttpContext.Current.Response.Write("Impersonate<br />");
        base.OnLoad(e);
    }

    protected override void OnUnload(EventArgs e)
    {
        base.OnUnload(e);
        _ImpersonationUndo();
    }

    protected void _ImpersonationUndo()
    {
        if (m_wic != null)
        {
            m_wic.Undo();
            HttpContext.Current.Response.Write("Impersonate undo<br />");
        }
        m_wic = null;
    }
}

表单页面指令:

<%@ Page Async="true" Language="C#" AutoEventWireup="true" Inherits="ProxyAddresses" Codebehind="ProxyAddresses.aspx.cs" %>

类声明:

public partial class ProxyAddresses : ImpersonatedPage

页面加载:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("Page_Load: " + WindowsIdentity.GetCurrent().Name + "<br />");

    if (!IsPostBack)
    {
        RegisterAsyncTask(new PageAsyncTask(InitialPageLoadAsync));
    }
    ...

异步函数:

private async Task InitialPageLoadAsync()
{
    Response.Write("InitialPageLoadAsync: " + WindowsIdentity.GetCurrent().Name + "<br />");

    await fnDoSomeAsyncWork();
    ...

按钮点击:

protected void idBtnSaveSrv_Click(object sender, EventArgs e)
{
    Response.Write("idBtnSaveSrv_Click: " + WindowsIdentity.GetCurrent().Name + "<br />");
    ...

调试输出 - 初始请求:

  • 模仿
  • Page_Load:DOMAIN\myuser
  • InitialPageLoadAsync:IIS APPPOOL\appuser(为什么?)
  • [页面内容]
  • 模拟撤销

调试输出 - 按钮点击:

  • 模仿
  • Page_Load:DOMAIN\myuser
  • idBtnSaveSrv_Click:IIS APPPOOL\appuser(为什么?)
  • [页面内容]
  • 模拟撤销

最佳答案

看起来好像您在表单页面指令中缺少 Async="true",详细信息 here .试试这个:

<%@ Page Async="true" Language="C#" Async="true"
    AutoEventWireup="true" Inherits="ProxyAddresses" 
    Codebehind="ProxyAddresses.aspx.cs" %>

关于c# - 从 ASP.Net 调用异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36156505/

相关文章:

c# - NUnit Assert - 显示完整的错误信息

c# - TFS 构建工作流 - SC.EXE 的 InvokeProcess?还是自定义事件?

asp.net - 3 列布局,当第 1 列和第 3 列为空时,希望中间列拉伸(stretch)得更宽

javascript - 如何使用 JavaScript 或 jQuery 清除 Google Chrome、Mozilla Firefox 和 Safari 中的剪贴板数据

c# - WebClient 与 HttpClient - 异步请求

c# - 在 c# 中为 twitter 实现短网址(tinyurls)?

c# - 如何正确测试 .net 服务逻辑

asp.net - ASP.NET 中图像的 ImgUrl 属性的预处理器指令存在问题

c# - 如果异步方法是单线程的,它如何在后台运行?

javascript - 多个 Async/Await Try-Catch block