Pergunta

Eu estou usando o Yahoo Autor, parte do Yahoo UI Library, no meu ASP.Net site para permitir que os usuários fazer upload de arquivos.Para quem não conhece, o autor trabalha usando um Flash applet para me dar mais controle sobre a caixa de diálogo Abrir.Eu posso especificar um filtro para tipos de arquivo, permitir que vários arquivos sejam seleccionados, etc.É ótimo, mas ele tem a seguinte limitação documentada:

Devido a um Flash conhecidos erro, o Uploader executado no Firefox no Windows não envia os cookies corretos com o upload;em vez de enviar o Firefox os cookies, ele envia o Internet Explorer cookies para o respectivo domínio.Como uma solução alternativa, sugerimos que seja usando um cookieless método de carregamento ou anexar documento.cookie para a solicitação de carregamento.

Assim, se um usuário estiver usando o Firefox, eu não dependem de cookies para manter seus sessão quando eles o upload de um arquivo.Eu preciso de sua sessão porque eu preciso saber quem eles são!Como solução, eu estou utilizando o objecto de Aplicação assim:

Guid UploadID = Guid.NewGuid();
Application.Add(Guid.ToString(), User);

Então, eu estou criando um ID exclusivo e usá-lo como uma chave para armazenar o Page.User objeto do âmbito de Aplicação.Eu que incluem a IDENTIFICAÇÃO como uma variável no POST quando o arquivo é carregado.Em seguida, o manipulador de que aceita o upload do arquivo, eu pegue o objeto de Usuário assim:

IPrincipal User = (IPrincipal)Application[Request.Form["uploadid"]];

Isso realmente funciona, mas tem dois flagrantes desvantagens:

  • Se o IIS, o pool de aplicativo, ou até mesmo apenas o aplicativo é reiniciado entre o momento em que o usuário visita a página de carregamento, e, na verdade, faz um upload de um arquivo, o seu "uploadid" é excluído do âmbito de aplicação e o upload de falhar, porque eu não posso autenticar-los.

  • Se eu escala para um farm de servidores web (ou possivelmente até mesmo um jardim da web) cenário, isso vai quebrar completamente.Eu não poderia estar preocupado, exceto eu faço o plano na escala este app no futuro.

Alguém tem uma maneira melhor?Existe uma maneira para eu passar a real ASP.Net ID de sessão em um POST variável e, em seguida, utilizar esse ID no outro final para recuperar a sessão?

Eu sei que eu posso obter a ID de sessão através de Session.SessionID, e eu sei como usar o YUI post para a página seguinte.O que eu não sei é como usar o que SessionID para pegar a sessão do servidor de estado.

Sim, eu estou usando um servidor de estado para armazenar as sessões, para que eles persistem aplicação/IIS é reiniciado, e vai trabalhar em um cenário de farm da web.

Foi útil?

Solução

Aqui é um post do mantenedor do Conteúdo voltado o que explica como carregar a sessão a partir de uma IDENTIFICAÇÃO armazenados no Pedido.O formulário.Eu imagino a mesma coisa que trabalho para o Yahoo componente.

Observação a segurança avisos de isenção de responsabilidade no final do post.


Incluindo um Mundial.asax arquivo e o código a seguir você pode substituir a falta de cookie de ID de Sessão:

using System;
using System.Web;

public class Global_asax : System.Web.HttpApplication
{
    private void Application_BeginRequest(object sender, EventArgs e)
    {
        /* 
        Fix for the Flash Player Cookie bug in Non-IE browsers.
        Since Flash Player always sends the IE cookies even in FireFox
        we have to bypass the cookies by sending the values as part of the POST or GET
        and overwrite the cookies with the passed in values.

        The theory is that at this point (BeginRequest) the cookies have not been ready by
        the Session and Authentication logic and if we update the cookies here we'll get our
        Session and Authentication restored correctly
        */

        HttpRequest request = HttpContext.Current.Request;

        try
        {
            string sessionParamName = "ASPSESSID";
            string sessionCookieName = "ASP.NET_SESSIONID";

            string sessionValue = request.Form[sessionParamName] ?? request.QueryString[sessionParamName];
            if (sessionValue != null)
            {
                UpdateCookie(sessionCookieName, sessionValue);
            }
        }
        catch (Exception ex)
        {
            // TODO: Add logging here.
        }

        try
        {
            string authParamName = "AUTHID";
            string authCookieName = FormsAuthentication.FormsCookieName;

            string authValue = request.Form[authParamName] ?? request.QueryString[authParamName];
            if (authValue != null)
            {
                UpdateCookie(authCookieName, authValue);
            }
        }
        catch (Exception ex)
        {
            // TODO: Add logging here.
        }
    }

    private void UpdateCookie(string cookieName, string cookieValue)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookieName);
        if (cookie == null)
        {
            HttpCookie newCookie = new HttpCookie(cookieName, cookieValue);
            Response.Cookies.Add(newCookie);
        }
        else
        {
            cookie.Value = cookieValue;
            HttpContext.Current.Request.Cookies.Set(cookie);
        }
    }
}

Aviso De Segurança: Não basta copiar e colar este código na sua ASP.Net aplicação sem saber o que você está fazendo.Ele apresenta problemas de segurança e a possibilidade de Cross-site Scripting.

Outras dicas

Você pode obter o seu atual SessionID do código a seguir:

string sessionId = HttpContext.Current.Session.SessionID;

Em seguida, você pode alimentar-se de que em um campo oculto talvez e, em seguida, aceder a esse valor através de YUI.

É apenas um se, então espero que você não terá quaisquer problemas de escala.Segurança-problemas, porém, que eu não sei.

Depender este post de blog, aqui está uma função que deve ajudá-lo a sessão, para que qualquer utilizador com base no ID de sessão, apesar de não ser bonito:

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;
}

O ASP.Net ID da Sessão é armazenado em Session.SessionID assim, você pode definir que em um campo oculto e, em seguida, enviá-lo para a próxima página.

Penso, no entanto, que, se o aplicativo for reiniciado, o identificador de sessão irá expirar se não armazenar suas sessões no sql server.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top