É este um bom caminho para obter um WebProfile?
-
02-07-2019 - |
Pergunta
Eu tenho um relato usuário que quando eles usam o botão Voltar para retornar a uma página web que voltar como uma pessoa diferente. Parece que eles podem estar acessando um perfil de usuários diferentes.
Aqui estão as partes importantes do 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;
}
Eu estou usando métodos estáticos e uma static WebProfile
porque eu preciso para usar o objeto de perfil em um static WebMethod
(pageMethod
ajax).
- Poderá isto conduzir ao objeto perfil que está sendo "compartilhada" por diferentes usuários?
- Am I não usar métodos estáticos e objetos corretamente?
A razão que eu mudei objeto WebProfile
a um objeto static
foi porque eu preciso acessar o objeto perfil dentro de um [WebMethod]
(chamado de javascript na página).
- Existe uma maneira de acessar um objeto de perfil dentro de um
[WebMethod]
? - Se não, quais as opções que eu tenho?
Solução
Um objeto estático é compartilhado entre todas as instâncias de um aplicativo por isso, se você alterar o valor de um objeto estático, que a alteração será refletida em todas as instâncias do aplicativo que acessar esse objeto. Portanto, se o seu perfil web é reatribuída por outro segmento (ou seja, um segundo usuário visitar uma página) inbetween você configurá-lo para o usuário atual, ele irá conter informações diferentes para o que você espera.
Para contornar este o seu código deve ser algo como:
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);
}
Note que o objeto estático não foi definido eo valor retornado deve ser atribuído a uma instância não estático da classe perfil web em seu método de chamada.
Outra opção é bloquear o seu variável estática durante todo o tempo ele está em uso, mas isso vai levar a uma severa degradação no desempenho como o bloqueio irá bloquear quaisquer outros pedidos para o recurso até que o segmento de bloqueio atual é completado - não é uma boa coisa em uma aplicação web.
Outras dicas
@Geri
Se o perfil não costuma mudar para o usuário tem a opção de armazená-lo no estado de sessão atual. Isto irá introduzir alguma sobrecarga de memória, mas, dependendo do tamanho do perfil e do número de usuários simultâneos isso poderia muito bem ser um não-problema. Você faria 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
}
Assim que o estado perfil é recuperado da sessão sempre que necessário e deve começar em torno da necessidade de variáveis ??estáticas.