Как получить доступ к сеансу в aspx, который был изменен в ashx?

Я использую uploadify для загрузки файлов, они автоматически отправляются в обработчик. Затем я изменяю сеанс в обработчике, который я настроил как статическое свойство в общем классе веб-сайта. Затем я пытаюсь получить доступ к тому же сеансу на странице aspx, и значение равно null. У меня такое ощущение, что это из-за файлов cookie, но должен быть способ обойти это, не раскрывая идентификатор сеанса в URL-адресе.

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

Как мне получить доступ и изменить текущий сеанс в файле ASHX БЕЗ изменения cookieless на true, а затем получить доступ к сеансу со страницы ASPX?

Я пробовал использовать HttpContext и использовать контекст, переданный в ASHX... ничего не работает.

то же, что и этот вопрос, но должен быть более безопасный способ: aspx">набор сеанса в ashx и получение этого сеанса на aspx

Любые идеи?


person Steve Stokes    schedule 22.01.2013    source источник
comment
Вы обращаетесь к странице ASPX и странице ASHX, используя одно и то же доменное имя?   -  person Mike Christensen    schedule 22.01.2013
comment
Я в разработке на локальном хосте, так что да.   -  person Steve Stokes    schedule 22.01.2013
comment
Хм странно. Я бы посмотрел на куки и посмотрел, какие есть пути. Может быть, куки привязаны только к одной странице или что-то в этом роде?   -  person Mike Christensen    schedule 22.01.2013
comment
Видимо проблема в браузере. IE копирует sessionid в ashx, chrome, ff и т.д.   -  person Steve Stokes    schedule 22.01.2013
comment
Нет, если файл cookie действителен для этого пути, браузер отправит его. Если вы смотрели на HTTP-трафик, возможно, он там есть. Попробуйте решение Win и посмотрите, работает ли оно.   -  person Mike Christensen    schedule 22.01.2013
comment
Это уже есть в моем коде и не работает.   -  person Steve Stokes    schedule 22.01.2013
comment
нашел это: stackoverflow.com/questions/43324/, но это не поможет.   -  person Steve Stokes    schedule 22.01.2013
comment
Как вы называете этот файл ASHX? Во-первых, вам нужно убедиться, что файл cookie устанавливается в ответ (для этого используйте Fiddler), а во-вторых, браузер правильно обрабатывает этот ответ и сохраняет файл cookie.   -  person Mike Christensen    schedule 22.01.2013
comment
Он вызывается из флэш-памяти, которая не передает идентификатор сеанса. это похоже на исправление: snipplr.com/view/15180   -  person Steve Stokes    schedule 22.01.2013


Ответы (2)


Я нашел ответ: когда обработчик вызывается из FLASH (например, swfupload или uploadify), он не передает текущий идентификатор сеанса обработчику. Затем обработчик создает НОВЫЙ сеанс. Чтобы исправить это, сделайте следующее:

Ваш пользовательский интерфейс: 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/

Вам может потребоваться использовать authid при использовании аутентификации форм:

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

добавьте это к параметру загрузчика в файле jQuery.

Затем добавьте следующее к глобальному:

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 и т. д.

person Steve Stokes    schedule 22.01.2013
comment
Рад, что вы поняли это, отстой, вам нужно прыгать через все эти обручи! - person Mike Christensen; 23.01.2013
comment
Да и неинтересно сталкиваться с такими проблемами. Меня раздражает, что по прошествии стольких лет до сих пор нет действительно чистого, красивого и простого решения для загрузки файлов для веб-форм. Всегда кажется, что где-то есть проблема. - person Steve Stokes; 23.01.2013
comment
Это именно то, что я искал. Это заслуживает моего голоса! Спасибо! - person Mausimo; 12.04.2013
comment
Я рад, что это помогло вам, было не весело выяснять, что происходит, лол. - person Steve Stokes; 03.06.2013

Context.Session is null.. потому что соединение с HttpHandler имеет другой Context.Session
(отладьте и попробуйте: Context.Session.SessionId, где находится fileInput, отличается от Context.Session.SessionId в Upload.ashx)!

Я предлагаю обходной путь: передать ссылку на элементы, которые вам нужны во втором сеансе (в моем примере я передаю исходный 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]

person Emanuele Greco    schedule 22.01.2013