Я столкнулся с проблемой с сеансом, я просто получаю данные, которые хранятся в сеансе, и я обновил один из элементов в этом списке, затем я проверяю некоторые условия. Если условие выполнено, то он должен обновляться только в сеансе.
Но проблема в том, что я не обновлял в сеансе, который он отражает.
Ниже приведен код, который я написал.
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
}
}
Надеюсь это поможет.