【问题标题】:Session_Start firing multiple timesSession_Start 多次触发
【发布时间】:2016-07-11 15:47:50
【问题描述】:

我有一个基础 web ui 项目,我还有其他“插件”项目,它们只是其他 mvc web 应用程序。

我从它们那里获取 dll 和视图,并将它们扔到我的主 web ui 的 bin 和视图文件夹中,以便可以随时添加或删除它们。

每个“插件”都包含一个 GET 方法,该方法从主 Web ui 调用以从每个“插件”加载菜单选项。

调用每个 URL 后,主 web ui 触发 `Session_Start'

menu.Append(HelperMethods.GetModuleMenuHTML(controller, SecurityController.CurrentDomain()));

public static string GetModuleMenuHTML(string controllerName, string currentDomain)
    {
        string html = string.Empty;
        try
        {
            //THIS LINE HERE IS CAUSING Session_Start to fire again
            //IN THE MAIN WEB UI
            html = new WebClient().DownloadString(string.Format("{0}/{1}/GetMenu", currentDomain, controllerName));
        }
        catch (Exception ex)
        {

        }
        return html;
    }

在调用 html = new WebClient().DownloadString(string.Format("{0}/{1}/GetMenu", currentDomain, controllerName)); 时导致 Session_Start 触发的原因是什么?如何防止这种情况发生?

这是否与我只是将另一个项目中的 dll 和视图作为“插件”(但它正确加载到我的 UI)中的 dll 和视图直接放入主 web ui 项目中,以便轻松添加和删除?

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    主要是因为这个:

    html = new WebClient().DownloadString(string.Format("{0}/{1}/GetMenu", currentDomain, controllerName));
    

    这一行使用WebClient类来获取html,但是WebClient类是无状态的,每次调用它都会使用另一个没有cookie的请求,所以服务器认为这是一个新的请求,并开始一个新的会话。

    【讨论】:

    • 那么打这个电话的最佳方式是什么?
    • 它实际上取决于很多事情,比如发送请求的表单是否与 asp.net 应用程序在同一个域中?那么最好直接调用而不是像现在那样使用它,您还可以选择转发 WebClient 请求附带的所有 cookie,但这将是相当糟糕的方法
    • 其他“插件”没有参考主 web ui。 webui 是 company.webui 插件是 company.module.nameofmodule
    • @Tsukasa 您可以将其用作更干净的方式stackoverflow.com/q/483091/1419970
    • 感谢我改用 RenderRazorView。
    【解决方案2】:

    WebClient 请求正在递归地启动一个新会话。作为 hack,您可以修改 Session_Start() 以检查传入的 url 是否为 /{controller}/GetMenu 并简单地避免 WebClient 调用。请参阅:https://stackoverflow.com/a/18656561

    否则,也许用 SessionStateAttribute (https://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute(v=vs.118).aspx) 装饰您的 MenuController 可能会完全避免 Session_Start(如果 GetMenu() 不使用会话状态)。

    【讨论】:

    • 在“插件”作品中完美使用[SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)]。就我在这里所做的而言,这是实现此类事情的正确方法还是不好的做法,因为有很多方法可以完成任务。
    • 我同意下面的 MoustafaS。我会尝试使用 RenderViewToString()(在此处实现 stackoverflow.com/a/2759898/154355)。这将避免http请求并提高性能。由于 GetMenu() 不使用任何会话状态,是否也可以在 Application_Start 中渲染一次并在 Session_Start 中使用缓存版本?
    • 主 web ui 不知道包含 GetMenu 的其他控制器,因此我需要将控制器名称作为字符串以及操作 GetMenu 传递。有没有办法修改它?
    猜你喜欢
    • 2016-11-02
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多