Сессия автоматически обновляется в asp.net

Вопрос:

Я столкнулся с проблемой с сеансом, я просто получаю данные, которые хранятся в сеансе, и я обновил один из элементов в этом списке, затем я проверяю некоторые условия. Если условие выполнено, то он должен обновляться только в сеансе.

Но проблема в том, что я не обновлял в сеансе, который он отражает.

Ниже приведен код, который я написал.

int index = (Convert.ToInt32(context.Request["rowIndex"]) - 1);
List<UserOrganizationMapping> updateUserOrgmapping = SessionHelper.GetSessionValue<List<UserOrganizationMapping>>("LstUserOrgMapping");

if (updateUserOrgmapping != null && updateUserOrgmapping.Count > 0)
{
updateUserOrgmapping[index].OrganizationName = context.Request["updateOrganizationName"];
if (context.Request["updateOrganizationVal"] != "Select")
{
updateUserOrgmapping[index].OrganizationId = Convert.ToInt32(context.Request["updateOrganizationVal"]);
}
updateUserOrgmapping[index].ModifiedBy = System.Web.HttpContext.Current.Session["UserID"].ToString();
updateUserOrgmapping[index].StartDate = Convert.ToDateTime(context.Request["updateStartDate"]);
updateUserOrgmapping[index].EndDate = Convert.ToDateTime(context.Request["updateEndDate"]);
string error = VerifyOverlapping(updateUserOrgmapping);
if (error != null)
{
GetSerializable(context, error);
}
else
{
updateUserOrgmapping = SessionHelper.GetSessionValue<List<UserOrganizationMapping>>("LstUserOrgMapping").ToList();
SessionHelper.SetSessionValue("LstUserOrgMapping", updateUserOrgmapping);
}

}

Лучший ответ:

Это связано с тем, что то, что вы получаете при выполнении SessionHelper.GetSessionValue является ссылкой на объект, поэтому все последующие манипуляции с этим объектом отражаются там, где находятся фактические данные (куча). И именно поэтому вызов SessionHelper.SetSessionValue является избыточным в вашем случае.

Вы можете исправить эту проблему, скопировав содержимое списка, которое вы получаете из сеанса, на новый объект и выполните все свои манипуляции с этим недавно созданным объектом:

var updateUserOrmapping = new List<UserOrganizationMapping>(
  SessionHelper.GetSessionValue<List<UserOrganizationMapping>>("LstUserOrgMapping")
);

РЕДАКТИРОВАТЬ:

Как вы уже упоминали, вышеупомянутое решение все еще недостаточно, и это потому, что, хотя у нас есть новая ссылка на сам список, элементы списка, которые мы скопировали по ссылке, по-прежнему остаются теми же, что и в куче.

В основном в вашем случае вам нужно вернуться к исходному состоянию экземпляра целевого объекта (updateUserOrgmapping[index]) при возникновении ошибки. Вот пример (не очень элегантный, но вы понимаете):

var originalOrganizationName = updateUserOrgmapping[index].OrganizationName;
var originalOrganizationId = updateUserOrgmapping[index].OrganizationId;
var originalModifiedBy = updateUserOrgmapping[index].ModifiedBy;
var originalStartDate = updateUserOrgmapping[index].StartDate;
var originalEndDate = updateUserOrgmapping[index].EndDate;

updateUserOrgmapping[index].OrganizationName = context.Request["updateOrganizationName"];

// ...

string error = VerifyOverlapping(updateUserOrgmapping);
if (error != null)
{
    updateUserOrgmapping[index].OrganizationName = originalOrganizationName;
    updateUserOrgmapping[index].OrganizationId = originalOrganizationId;
    updateUserOrgmapping[index].ModifiedBy = originalModifiedBy;
    updateUserOrgmapping[index].StartDate = originalStartDate;
    updateUserOrgmapping[index].EndDate = originalEndDate;

    GetSerializable(context, error);
}

Более элегантным решением, вероятно, было бы заставить UserOrganizationMapping поддерживать глубокое копирование своего состояния, а затем вы могли бы сделать что-то вроде этого:

string VerifyOverlapping(IList<UserOrganizationMapping> mappings, UserOrganizationMapping modifiedMapping, int modifiedMappingIndex)
{
    string ret = null;

    // Keeping the reference to the original mapping.
    var originalMapping = mappings[modifiedMappingIndex];

    // Temporarily inserting the modified mapping for overlapping check.
    mappings[modifiedMappingIndex] = modifiedMapping;

    ret = VerifyOverlapping(mappings);

    // Getting the original value back on error.
    if (ret != null)
        mappings[modifiedMappingIndex] = originalMapping;

    return ret;
}

// ...    

int index = (Convert.ToInt32(context.Request["rowIndex"]) - 1);
var updateUserOrgmapping = SessionHelper.GetSessionValue<List<UserOrganizationMapping>>("LstUserOrgMapping");

if (updateUserOrgmapping != null && updateUserOrgmapping.Count > 0)
{
    var mapping = new UserOrganizationMapping(updateUserOrgmapping[index])
    {
        OrganizationName = context.Request["updateOrganizationName"],
        ModifiedBy = System.Web.HttpContext.Current.Session["UserID"].ToString(),
        StartDate = Convert.ToDateTime(context.Request["updateStartDate"]),
        EndDate = Convert.ToDateTime(context.Request["updateEndDate"])  
    };

    if (context.Request["updateOrganizationVal"] != "Select")
        mapping.OrganizationId = Convert.ToInt32(context.Request["updateOrganizationVal"]); 

string error = VerifyOverlapping(updateUserOrgmapping, mapping, index);

if (error != null)
    GetSerializable(context, error);

// ...

public class UserOrganizationMapping
{
    public UserOrganizationMapping() { }
    public UserOrganizationMapping(UserOrganizationMapping copyFrom)
    {
        this.Id = copyFrom.Id;
        // Copy all field values
    }
}

Надеюсь это поможет.

Оцените статью
TechArks.Ru
Добавить комментарий