【问题标题】:How to access session in aspx that was modified in ashx?如何访问在 ashx 中修改的 aspx 中的会话?
【发布时间】:2013-01-06 01:58:29
【问题描述】:

我正在使用 uploadify 上传文件,它们会自动发布到处理程序。然后,我在处理程序中修改会话,该处理程序已设置为网站公共类中的静态属性。然后我尝试在 aspx 页面中访问同一个会话,并且值为 null。我感觉这是因为 cookie,但需要有一种方法来解决这个问题,而不会在 url 中暴露 sessionid。

ASHX:

public class Upload : IHttpHandler, IReadOnlySessionState, IRequiresSessionState 
{

    public void ProcessRequest(HttpContext context)
    {
        ...
        CMSSession.Current.UploadedFiles.Add(fileName);
    }
}

会话类:

public class CMSSession
{    
    public static CMSSession Current
    {
        get
        {
            CMSSession session = (CMSSession)HttpContext.Current.Session["__CMSSession__"];
            if (session == null)
            {
                session = new CMSSession();
                HttpContext.Current.Session["__CMSSession__"] = session;
            }
            return session;
        }
    }

    public List<string> UploadedFiles { get; set; }
}

ASPX:

if (CMSSession.Current.UploadedFiles != null)
{
    ...
}
else
{
    IT'S ALWAYS NULL
}

Web.Config:

<sessionState mode="InProc" cookieless="false" /> - causes session to always null in aspx when modified in ashx
<sessionState mode="InProc" cookieless="true" /> - session value is not null, but sessionid is exposed in the url

如何在不将 cookieless 更改为 true 的情况下访问和修改 ASHX 文件中的当前会话,然后从 ASPX 页面访问会话?

我尝试过使用 HttpContext 并使用传递给 ASHX 的上下文...没有任何效果。

与此问题相同,但必须有更安全的方法:session set in ashx and get that session on aspx

有什么想法吗?

【问题讨论】:

  • 你访问的ASPX页面和ASHX页面是同一个域名吗?
  • 我在本地主机上的开发中,所以是的。
  • 嗯,很奇怪。我会查看 cookie 并查看路径是什么。也许 cookie 仅适用于单个页面或其他内容?
  • 显然是浏览器问题。 IE复制sessionid到ashx,chrome,ff等都没有。
  • 不,如果 cookie 对该路径有效,浏览器将发送它。如果您查看 HTTP 流量,它可能就在那里。试试 Win 的解决方案,看看是否可行。

标签: c# asp.net file-upload webforms ashx


【解决方案1】:

我找到了答案:当从 FLASH(如 swfupload 或 uploadify)调用处理程序时,它不会将当前 sessionid 传递给处理程序。然后处理程序创建一个新会话。要解决此问题,请执行以下操作:

您的用户界面:JavaScript:

$(Selector).uploadify({
    swf: 'uploadify.swf',
    uploader: 'Upload.ashx?ASPSESSID=<%=Session.SessionID%>'   
});

添加到:Global.asax:

void Application_BeginRequest(object sender, EventArgs e)
{
    try
    {
        string session_param_name = "ASPSESSID";
        string session_cookie_name = "ASP.NET_SESSIONID";
        string session_value = Request.Form[session_param_name] ?? Request.QueryString[session_param_name];
        if (session_value != null) { UpdateCookie(session_cookie_name, session_value); }
    }
    catch (Exception) { }
}

void UpdateCookie(string cookie_name, string cookie_value)
{
    HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
    if (cookie == null)
    {
        HttpCookie cookie1 = new HttpCookie(cookie_name, cookie_value);
        Response.Cookies.Add(cookie1);
    }
    else
    {
        cookie.Value = cookie_value;
        HttpContext.Current.Request.Cookies.Set(cookie);
    }
}

上传并简化来自: http://snipplr.com/view/15180/

如果使用formsauthentication,您可能需要使用authid:

&AUTHID=<%= Request.Cookies[FormsAuthentication.FormsCookieName] == null ? "" : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>

将其附加到 jQuery 中的 uploader 参数。

然后将以下内容添加到全局中:

try
    {
        string auth_param_name = "AUTHID";
        string auth_cookie_name = FormsAuthentication.FormsCookieName;
        string auth_value = Request.Form[auth_param_name] ?? Request.QueryString[auth_param_name];

        if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); }
    }
    catch (Exception) { }

您现在可以在 IE、Chrome、FF 等中从处理程序访问相同的会话(甚至使用我在上面问题中使用的静态会话对象)。

【讨论】:

  • 很高兴你知道了这一点,太糟糕了,你必须跳过所有这些障碍!
  • 是的,遇到这样的问题并不好玩。我发现这些年来仍然没有真正干净、漂亮、简单的网络表单文件上传解决方案很烦人。似乎总在某个地方出现问题。
  • 这正是我想要的。这值得我投赞成票!谢谢!
  • 很高兴这对您有所帮助,搞清楚发生了什么并不好玩,哈哈。
【解决方案2】:

Context.Session is null.. 因为与HttpHandler 的连接有另一个Context.Session
(调试并尝试:Context.Session.SessionId 在哪里 fileInput 与 Upload.ashx 中的Context.Session.SessionId 不同)!

我建议一种解决方法:在第二个会话中传递对您需要的元素的引用(在我的示例中,我使用 sessionId 变量传递原始 SessionId

....
var sessionId = "<%=Context.Session.SessionID%>";
var theString = "other param,if needed";
$(document).ready(function () {
    $('#fileInput').uploadify({
        'uploader': '<%=ResolveUrl("~/uploadify/uploadify.swf")%>',
        'script': '<%=ResolveUrl("~/Upload.ashx")%>',
        'scriptData': { 'sessionId': sessionId, 'foo': theString },
        'cancelImg': '<%=ResolveUrl("~/uploadify/cancel.png")%>',
 ....

并在 .ashx 文件中使用这些项目。

public void ProcessRequest(HttpContext context)
{
    try
    {
       HttpPostedFile file = context.Request.Files["Filedata"];
       string sessionId = context.Request["sessionId"].ToString();
      ....

如果您需要共享复杂元素,请使用 Context.Application 而不是 Context.Session,使用原始 SessionID:Context.Application["SharedElement"+SessionID]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2023-03-28
    • 2014-08-27
    相关资源
    最近更新 更多