C# 我可以将ASP.Net会话ID放入隐藏的表单字段中吗?

C# 我可以将ASP.Net会话ID放入隐藏的表单字段中吗?,c#,asp.net,session,yui,C#,Asp.net,Session,Yui,我在ASP.Net网站上使用Yahoo Uploader,Yahoo UI库的一部分,允许用户上传文件。对于那些不熟悉的人,上传程序通过使用Flash小程序来让我更好地控制FileOpen对话框。我可以为文件类型指定一个过滤器,允许选择多个文件,等等。这很好,但它有以下限制: 由于一个已知的Flash bug,Windows中Firefox中运行的上传程序在上传时没有发送正确的cookie;它不发送Firefox cookies,而是发送相应域的Internet Explorer cookies

我在ASP.Net网站上使用Yahoo Uploader,Yahoo UI库的一部分,允许用户上传文件。对于那些不熟悉的人,上传程序通过使用Flash小程序来让我更好地控制FileOpen对话框。我可以为文件类型指定一个过滤器,允许选择多个文件,等等。这很好,但它有以下限制:

由于一个已知的Flash bug,Windows中Firefox中运行的上传程序在上传时没有发送正确的cookie;它不发送Firefox cookies,而是发送相应域的Internet Explorer cookies。作为一种解决方法,我们建议使用无cookie上传方法或将document.cookie附加到上传请求

因此,如果用户正在使用Firefox,我不能依赖cookies在他们上传文件时保持会话。我需要他们的治疗,因为我需要知道他们是谁!作为一种解决方法,我使用Application对象:

Guid UploadID = Guid.NewGuid();
Application.Add(Guid.ToString(), User);
IPrincipal User = (IPrincipal)Application[Request.Form["uploadid"]];
因此,我正在创建一个唯一的ID,并将其用作在应用程序范围中存储
Page.User
对象的键。我在上传文件时将该ID作为变量包含在POST中。然后,在接受文件上载的处理程序中,我抓取用户对象:

Guid UploadID = Guid.NewGuid();
Application.Add(Guid.ToString(), User);
IPrincipal User = (IPrincipal)Application[Request.Form["uploadid"]];
这实际上是可行的,但它有两个明显的缺点:

  • 如果IIS、应用程序池甚至应用程序在用户访问上载页面和实际上载文件之间重新启动,他们的“uploadid”将从应用程序范围中删除,并且上载失败,因为我无法对他们进行身份验证

  • 如果我曾经扩展到一个网络农场(甚至可能是一个网络花园)场景,这将完全打破。我可能不担心,但我确实计划在将来扩展这个应用程序

有人有更好的方法吗?有没有办法在POST变量中传递实际的ASP.Net会话ID,然后在另一端使用该ID检索会话

我知道我可以通过
session.SessionID
获取会话ID,并且我知道如何使用YUI将其发布到下一页。我不知道的是如何使用
SessionID
从状态服务器获取会话


是的,我正在使用状态服务器存储会话,因此它们将持久化应用程序/IIS重新启动,并将在web场场景中工作。

ASP.Net会话ID存储在
Session.SessionID
中,因此您可以将其设置在隐藏字段中,然后将其发布到下一页


但是,我认为,如果应用程序重新启动,sessionID将在您不启动时过期。

您可以通过以下代码获取当前sessionID:

string sessionId = HttpContext.Current.Session.SessionID;
然后你可以把它输入一个隐藏的字段,然后通过YUI访问这个值

这只是一个get,所以希望您不会有任何缩放问题。但我不知道安全性问题。

是维护人员的一篇文章,解释了如何从Request.Form中存储的ID加载会话。我想同样的事情也适用于雅虎组件

请注意文章底部的安全免责声明


通过包含Global.asax文件和以下代码,您可以覆盖丢失的会话ID cookie:

安全警告:不要在不知道自己在做什么的情况下将此代码复制并粘贴到ASP.Net应用程序中。它介绍了安全问题和跨站点脚本的可能性

依赖于,这里有一个函数可以根据会话ID为任何用户获取会话,尽管它并不漂亮:

public SessionStateStoreData GetSessionById(string sessionId)
{
    HttpApplication httpApplication = HttpContext.ApplicationInstance;

    // Black magic #1: getting to SessionStateModule
    HttpModuleCollection httpModuleCollection = httpApplication.Modules;
    SessionStateModule sessionHttpModule = httpModuleCollection["Session"] as SessionStateModule;
    if (sessionHttpModule == null)
    {
        // Couldn't find Session module
        return null;
    }

    // Black magic #2: getting to SessionStateStoreProviderBase through reflection
    FieldInfo fieldInfo = typeof(SessionStateModule).GetField("_store", BindingFlags.NonPublic | BindingFlags.Instance);
    SessionStateStoreProviderBase sessionStateStoreProviderBase = fieldInfo.GetValue(sessionHttpModule) as SessionStateStoreProviderBase;
    if (sessionStateStoreProviderBase == null)
    {
        // Couldn't find sessionStateStoreProviderBase
        return null;
    }

    // Black magic #3: generating dummy HttpContext out of the thin air. sessionStateStoreProviderBase.GetItem in #4 needs it.
    SimpleWorkerRequest request = new SimpleWorkerRequest("dummy.html", null, new StringWriter());
    HttpContext context = new HttpContext(request);

    // Black magic #4: using sessionStateStoreProviderBase.GetItem to fetch the data from session with given Id.
    bool locked;
    TimeSpan lockAge;
    object lockId;
    SessionStateActions actions;
    SessionStateStoreData sessionStateStoreData = sessionStateStoreProviderBase.GetItem(
        context, sessionId, out locked, out lockAge, out lockId, out actions);
    return sessionStateStoreData;
}

找到@shamp00上的链接。如果您可以编辑答案以包含相关文本,将有所帮助