Pregunta

Tengo un usuario que informa que cuando usan el botón Atrás para regresar a una página web, regresan como una persona diferente. Parece que pueden estar accediendo a un perfil de usuario diferente.

Estas son las partes importantes del código:

//here's the code on the web page

public static WebProfile p = null;

protected void Page_Load(object sender, EventArgs e)
{
    p = ProfileController.GetWebProfile();
    if (!this.IsPostBack)
    {
         PopulateForm();
    }       
}

//here's the code in the "ProfileController" (probably misnamed)
public static WebProfile GetWebProfile()
{
    //get shopperID from cookie
    string mscsShopperID = GetShopperID();
    string userName = new tpw.Shopper(Shopper.Columns.ShopperId,        mscsShopperID).Email;
    p = WebProfile.GetProfile(userName); 
    return p;
}

Estoy usando métodos estáticos y un static WebProfile porque necesito usar el objeto de perfil en un static WebMethod (ajax pageMethod ) .

  • ¿Podría esto llevar a que el objeto de perfil sea " compartido " por diferentes usuarios?
  • ¿No estoy usando métodos y objetos estáticos correctamente?

La razón por la que cambié el objeto WebProfile a un objeto static fue porque necesito acceder al objeto de perfil dentro de un [WebMethod] (llamado de javascript en la página).

  • ¿Hay alguna forma de acceder a un objeto de perfil dentro de un [WebMethod] ?
  • Si no, ¿qué opciones tengo?
¿Fue útil?

Solución

Un objeto estático se comparte en todas las instancias de una aplicación, por lo que si modifica el valor de un objeto estático, esa alteración se reflejará en todas las instancias de la aplicación que accedan a ese objeto. Por lo tanto, si su perfil web es reasignado por otro hilo (es decir, un segundo usuario que visita una página) entre la configuración para el usuario actual, contendrá información diferente a la que espera.

Para evitar esto, su código debería verse así:

public WebProfile p = null;

protected void Page_Load(object sender, EventArgs e)
{
    p = ProfileController.GetWebProfile();
    if (!this.IsPostBack)
    {
         PopulateForm();
    }       
}

public static WebProfile GetWebProfile()
{
    //get shopperID from cookie
    string mscsShopperID = GetShopperID();
    string userName = new tpw.Shopper(Shopper.Columns.ShopperId,        mscsShopperID).Email;
    return WebProfile.GetProfile(userName); 
}

Tenga en cuenta que el objeto estático no se ha establecido y el valor devuelto debe asignarse a una instancia NO ESTÁTICA de la clase de perfil web en su método de llamada.

Otra opción es BLOQUEAR su variable estática durante todo el tiempo que esté en uso, pero esto conducirá a una degradación severa en el rendimiento ya que el bloqueo bloqueará cualquier otra solicitud del recurso hasta que se complete el hilo de bloqueo actual, lo que no es bueno cosa en una aplicación web.

Otros consejos

@Geri

Si el perfil no cambia a menudo para el usuario, tiene la opción de almacenarlo en el estado actual de la sesión. Esto introducirá algo de sobrecarga de memoria, pero dependiendo del tamaño del perfil y el número de usuarios simultáneos, esto podría ser un problema. Harías algo como:

public WebProfile p = null;
private readonly string Profile_Key = "CurrentUserProfile"; //Store this in a config or suchlike

protected void Page_Load(object sender, EventArgs e)
{
    p = GetProfile();

    if (!this.IsPostBack)
    {
        PopulateForm();
    }       
}

public static WebProfile GetWebProfile() {} // Unchanged

private WebProfile GetProfile()
{
    if (Session[Profile_Key] == null)
    {
        WebProfile wp = ProfileController.GetWebProfile();
        Session.Add(Profile_Key, wp);
    }
    else
        return (WebProfile)Session[Profile_Key];
}

[WebMethod]
public MyWebMethod()
{
    WebProfile wp = GetProfile();
    // Do what you need to do with the profile here
}

Para que el estado del perfil se recupere de la sesión siempre que sea necesario y se evite la necesidad de variables estáticas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top