Это правильный способ получить веб-профиль?

StackOverflow https://stackoverflow.com/questions/128857

  •  02-07-2019
  •  | 
  •  

Вопрос

У меня есть пользователь, который сообщает, что, когда он использует кнопку «Назад», чтобы вернуться на веб-страницу, он возвращается как другой человек.Похоже, они могут получить доступ к другому профилю пользователя.

Вот важные части кода:

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

Я использую статические методы и static WebProfile потому что мне нужно использовать объект профиля в static WebMethod (аякс pageMethod).

  • Может ли это привести к тому, что объект профиля будет «совместно использоваться» разными пользователями?
  • Я неправильно использую статические методы и объекты?

Причина, по которой я изменился WebProfile возражать против static объект был потому, что мне нужно получить доступ к объекту профиля внутри [WebMethod] (вызывается из JavaScript на странице).

  • Есть ли способ получить доступ к объекту профиля внутри [WebMethod]?
  • Если нет, то какой у меня есть выбор?
Это было полезно?

Решение

Статический объект является общим для всех экземпляров приложения, поэтому, если вы измените значение статического объекта, это изменение будет отражено во всех экземплярах приложения, которые обращаются к этому объекту.Поэтому, если ваш веб-профиль переназначается другим потоком (т.второй пользователь, посещающий страницу) между тем, как вы настроите ее для текущего пользователя, она будет содержать информацию, отличную от той, которую вы ожидаете.

Чтобы обойти это, ваш код должен выглядеть примерно так:

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

Обратите внимание, что статический объект не был установлен, и возвращаемое значение должно быть присвоено НЕСТАТИЧЕСКОМу экземпляру класса веб-профиля в вызывающем методе.

Другой вариант — ЗАБЛОКИРОВАТЬ вашу статическую переменную на все время ее использования, но это приведет к серьезному снижению производительности, поскольку блокировка будет блокировать любые другие запросы к ресурсу до тех пор, пока текущий блокирующий поток не завершится, что не очень хорошо в случае веб-приложение.

Другие советы

@Гери

Если профиль пользователя не меняется часто, у вас есть возможность сохранить его в текущем состоянии сеанса.Это приведет к некоторым издержкам памяти, но в зависимости от размера профиля и количества одновременных пользователей это вполне может быть не проблемой.Вы бы сделали что-то вроде:

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
}

Таким образом, состояние профиля извлекается из сеанса всякий раз, когда это необходимо, и позволяет избежать необходимости в статических переменных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top