Generic Lists in a HttpSessionState stored in SQL - c#

I'm working on a aspx application (C#), where I'm using HttpSessionState to save different objects in code behind between view changes. Some of these objects containts generic lists (List<T>), but those lists doesn't seem to be saved when I'm using an SQL database to store the state (sessionState mode = "SQLServer"). All other properties in the object gets saved, but when I try to retrieve the list, I get empty lists.
The funny thing is that it all works fine if I use sessionState mode = "InProc".
My classes have the Serializable attribute. I'm running C#/.NET 4.0.
Any ideas would be appreciated!
EDIT:
Just to clarify with some code (not verbatim!).
I have the classes I want to save (instances of) to my Session State:
public class MyClass
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public List<MyOtherClass> Property3 { get; set; }
}
public class MyOtherClass
{
public string AnotherProperty1 { get; set; }
public string AnotherProperty2 { get; set; }
}
Then, in my Code Behind - one action saves objects of the previous classes:
public void MyMethod()
{
MyClass myClass = new MyClass()
{
Property1 = "One string",
Property2 = "One other string",
Property3 = new List<MyOtherClass>() { new MyOtherClass() { AnotherProperty1 = "One", AnotherProperty2 = "Ohter" } }
};
HttpContext.Current.Session["MyKey"] = myClass;
}
...and another action will retrieve that object:
public void MyOtherMethod()
{
MyClass myClass = (MyClass)HttpContext.Current.Session["MyKey"];
int c = myClass.Property3.Count; // Will be 0!!
}
So myClass.Property1 and myClass.Property2 will hold the strings I set previously, but myClass.Property3 is an empty list.

The problem you are describing could happen if you
Store a reference to an object in that generic list that is valid when you store it, but
the reference is no longer valid on subsequent requests.
An example would be storing a reference to a control from the Page.Controls collection - this reference would not be valid if you try to retrieve it on another postback. In fact, the reference may just be cleaned up by garbage collection (thus why your list appears to be empty).
Without seeing your actual code, it's tough to say for sure (although your example code does a great job of clarifying what you mean). But this seems likely to me.

Related

Issue while invoking a class and storing data into it c#

I have a class like this
public class basic
{
public bool Success { get; set; } = false;
public string Message { get; set; } = string.Empty;
}
public class ServiceResponse<T>:basic
{
public T? Data { get; set; }
}
public class ServiceResponse2<T> : basic
{
public T?[] Data { get; set; }
}
And I invoke it in my controller like this
ServiceResponse2<string> response = new ServiceResponse2<string>();
response.Success = true;
response.Message = "success";
response.Data[0] = filename;
response.Data[1] = outname;
when I do, I get runtime error in my lastline as: Object reference not set to an instance of an object. I hovered on top of Data variables and the values were null. Can I know what I'm missing here? Apologies if its a dumb doubt
The problem is that Data is an array, and this is never initialized to an object. You need to initialize it, for example:
response.Data = new string[]{filename, outname};
Or
public T?[] Data { get; set; } = new T[2];
However, I would be careful with using an array like this. What does Data means? How should it be used? Why can I change it however and whenever I want? How is it related to the other properties? Does a specific index have some special meaning? Does it promise to hold some specific number of items?
If this is intended to be used for requests to some type of service it is normal to use some form of serialization to convert objects to data. And this is normally done fairly close to the communication layer, so that most of the code can handle typed objects, and only a small part need to handle bits and bytes.

Variables from a specific class equality both sides still changing together if one of the sides change

I am new to C# and WPF, and I am trying to define a new variable from a class and to give this new variable a value from an old variable and then make some changes to the new one. But the problem is that the new variable is still connected to the old variable and if I change anything in the new one, the changes will effect the old one:
MW.CurrentPreviewJob = addjob;
MW is another page than the page I am writing the code in,
and I define them as follows:
public static Job addjob;
public Job CurrentPreviewJob
{
get { return _currentPreviewJob; }
set {
_currentPreviewJob = value;
this.NotifyPropertyChanged("CurrentPreviewJob");
}
}
the class for the two variables is same and it is:
public partial class Job
{
public int JOB_ID { get; set; }
public string JOB_DESCRIPTION { get; set; }
public byte[] TARGET_IMAGE { get; set; }
public int JOB_USER { get; set; }
}
So how can I take the value of CurrentPreviewJob without stay connecting to it?
This is because an object of a class is a reference type.
Let's take a look at an example:
We create an object of your class:
Job someJob = new Job();
What exactly is someJob? Well, when you create an instance of an object it is held in special area of memory, and someJob holds a reference to it (which is an address under which the program can find the instance in the memory).
So when you do something like:
Job someOtherJob = someJob;
you actually tell someOtherJob object to hold reference to the same address in a memmory as someJob object. that's how reference types work.
Now, if you do, for example:
someOtherJob.JOB_DESCRIPTION = "I changed that description in some other job object";
This is what happens: program checks the address which is referenced by somOtherJob object, goes there, finds the instance, and change its JOB_DESCRIPTION property's value. BUT remember that someJob objct (the "old" one) has a reference to the same instance in the memory - hnce, it will have the same, changed JOB_DESCRIPTION.
The most elegant thing to do here is to implement some kind of cloning method on the Job class.
public partial class Job
{
public int JOB_ID { get; set; }
public string JOB_DESCRIPTION { get; set; }
public byte[] TARGET_IMAGE { get; set; }
public int JOB_USER { get; set; }
public Job Clone() {
Job clone = new Job();
clone.JOB_ID = this.JOB_ID;
clone.JOB_DESCRIPTION = this.JOB_DESCRIPTION;
clone.TARGET_IMAGE = this.TARGET_IMAGE;
clone.JOB_USER = this.JOB_USER;
return clone;
}
}
and use it like:
Job someOtherJob = someJob.Clone();
That happens because both CurrentPreviewJob and addjob are reference types. They both reference the same object in the memory. So whatever you do to one variable will also affect the other, since they are pointing to the same object. You can make your Job have a Clone method like this:
public partial class Job
{
public int JOB_ID { get; set; }
public string JOB_DESCRIPTION { get; set; }
public byte[] TARGET_IMAGE { get; set; }
public int JOB_USER { get; set; }
public Job Clone()
{
return new Job {
JOB_ID = this.JOB_ID,
JOB_DESCRIPTION = this.JOB_DESCRIPTION,
TARGET_IMAGE = this.TARGET_IMAGE,
JOB_USER = this.JOB_USER
};
}
}
Then you can assign your CurrentPreviewJob like this:
MW.CurrentPreviewJob = addjob.Clone();
This will make another object so your second variable is no longer linked to your previous.
Or another way is to make your class a struct
The problem is because Job is a class, and classes are reference types, meaning that if you assign one job variable to another, you just have too variables referencing the same data.
You could declare Job as a struct, which are value types and assignment would automatically create a copy.
I tend to avoid structs, simply because I don't like having to copy things around just to change properties, so I'd suggest adding an appropriate constructor to Job, like:
public Job(Job other) {
this.JOB_ID = other.JOB_ID;
this.JOB_DESCRIPTION = other.JOB_DESCRIPTION;
//...same for the other fields
}
Once you have the constructor, you can clone the object by doing:
var NewJob = new Job(OldJob);

How do I map List<T1> to List<T2> using LINQ (or otherwise)

Lately I've worked on some programs that involve translating objects across various data domains. So I have a lot of mapping methods (sometimes as extension methods) for translating one type of object to another similar type in a different domain. Often, I also need a way to translate a List<> to a List<> of said types. This always involves having a method that simply creates a List<> of the target type, runs a foreach loop to add every element of the source List<> (but using the mapping method on each) and returning the new list. It's feeling pretty repetitive and like there might be something built into the language to do this (perhaps in LINQ?). I've looked at several similar issues involving List.ForEach() and the pros and cons of it (not what I'm looking for anyway). I'll illustrate with some example code below. Maybe there is no way to do what I want, and if that's the answer, then that's the answer, but I hope maybe there is. Please note, this is obviously just example code and comments about my overall program design won't really add anything because this is a very small dummy version of the problem at hand.
class A
{
public Guid Id { get; set; }
public string Email { get; set; }
public string MemberCode { get; set; }
}
class B
{
public string Email { get; set; }
public string MemberCode { get; set; }
// My custom mapping method
public A MapToA()
{
return new A()
{
Id = Guid.NewGuid(),
Email = this.Email,
MemberCode = this.MemberCode
};
}
// For list mapping, I have this, but I'd prefer
// to do something else that could utilize my custom mapper.
// Perhaps a built in LINQ method?
public static List<A> MapToListOfA(List<B> listOfB)
{
List<A> listOfA = new List<A>();
foreach (var b in listOfB)
{
listOfA.Add(b.MapToA());
}
return listOfA;
}
}
// Class C shows what I currently do that I'd like to get
// away from:
class C
{
public List<A> ListOfA { get; set; }
// other properties unrelated to the problem
// This is how I might use the MapToListOfA method,
// but I'd rather have something better.
public C(List<B> listOfB)
{
this.ListOfA = B.MapToListOfA(listOfB);
}
}
// I'd like something more like this:
class D
{
public List<A> ListOfA { get; set; }
// other properties unrelated to the problem
public D(List<B> listOfB)
{
// This doesn't compile, of course, but I hope
// it illustrates what I'm intending to do:
this.ListOfA = listOfB.Select(b => b.MapToA());
}
}
// This doesn't compile, of course, but I hope
// it illustrates what I'm intending to do:
this.ListOfA = listOfB.Select(b => b.MapToA());
It doesn't compile because listOfB.Select(b => b.MapToA()) produces an instance of IEnumerable<A> which is not assignable to List<A>.
Use ToList and it should compile fine
this.ListOfA = listOfB.Select(b => b.MapToA()).ToList();

How to pass data between function calls

We can pass data between functions by using class objects. Like i have class
public class AddsBean
{
public long addId{get;set;}
public int bid { get; set; }
public long pointsAlloted { get; set; }
public string userId { get; set; }
public enum isApproved { YES, NO };
public DateTime approveDate { get; set; }
public string title { get; set; }
public string description { get; set; }
public string Link { get; set; }
public DateTime dateAdded { get; set; }
}
We can call function like public List<AddsBean> getAdds(string Id). This approach is good when you need all the variables of class. But what if you need only 2 or 3 variables of class?
Passing object of class is not good because it will be wastage of memory. Another possible solution is to make different classes of lesser variables but that is not practical.
What should we do that will best possible solution to fulfill motive and best according to performance also?
In Java - "References to objects are passed by value".. So, you dont pass the entire object, you just pass the reference to the object to the called function.
EG:
class A{
int i;
int j;
double k;
}
class B{
public static void someFunc(A a) // here 'a' is a reference to an object, we dont pass the object.
{
// some code
}
public static void main(String[] args){
A a = new A();
B.someFunc(a); // reference is being passed by value
}
}
first of all, as Java is pass by value and references typed, there is no need to worry about the memory wastage.
next, as you have mentioned, it is not good to pass all the object if you do not need them all, in some situation, it's true. as you need to protect your data in instance, thus you can use different granularity of class, for instance:
class A
{id, name}
class B extends A
{password,birthday}
by refer to different class you can control the granularity yourself, and provide different client with different scope of data.
But in some condition, you need to use a instance to store all data in the whole application, like configure data in hadoop, or some other configuration related instance.
Try to choose the most suitable scope!
If you're sure that this is the source of problems and you don't want to define a new class with a subset of the properties, .NET provides the Tuple class for grouping a small number of related fields. For example, a Tuple<int, int, string> contains two integers and a string, in that order.
public Tuple<string, long, DateTime> GetPointsData()
{
AddsBean bean = ... // Get your AddsBean somehow
return Tuple.Create<string, long, DateTime>(bean.userId, bean.pointsAlloted, bean.approveDate);
}
Once this method goes out of scope, there is no longer a live reference to the object bean referred to and will be collected by the garbage collector at some point in the future.
That said, unless you're sure that instances of the AddsBean class are having a noticeable negative effect on the performance of your app, you should not worry about it. The performance of your application is probably affected far more by other operations. Returning a reference type (a type defined with class instead of struct) only passes a reference to the object, not the data of the object itself.

Locking an object to prevent any data changes

Bit of an odd one this...
Lets say I have the following class:
public class Wibble
{
public string Foo {get;set;}
public string Bar {get;set;}
}
This class is used a process where the values of Foo and Bar are updated/changed. However after a certain point in the process I want to "lock" the instance to prevent any changes from being made. So the question is how best to do this?
A solution of sorts would be something like this:
public class Wibble
{
private string _foo;
private string _bar;
public bool Locked {get; set;}
public string Foo
{
get
{
return this._foo
}
set
{
if (this.Locked)
{
throw new ObjectIsLockedException()
}
this._foo = value;
}
}
public string Bar
{
get
{
return this._bar
}
set
{
if (this.Locked)
{
throw new ObjectIsLockedException()
}
this._bar = value;
}
}
}
However this seems a little inelegant.
The reason for wanting to do this is that I have an application framework that uses externally developed plugins that use the class. The Wibble class is passed into the plugins however some of them should never change the contents, some of them can. The intention behind this is to catch development integration issues rather than runtime production issues. Having the object "locked" allows is to quickly identify plugins that are not coded as specified.
I've implemented something similar to your locked pattern, but also with a read-only interface implemented by a private sub-class containing the actual class data, so that you could pass out what is clearly a read-only view of the data and which can't be up-casted to the original 'mutable version'. The locking was purely to prevent the data provider from making further changes after it had provided an immutable view.
It worked reasonably well, but was a bit awkward, as you've noted. I think it's actually cleaner to have mutable 'Builder' objects which can then generate immutable snapshots. Think StringBuilder and String. This means you duplicate some property code and have to write the routines to do the copying, but it's less awkward, in my opinion, than having a write-lock on every property. It's also evident at compile-time that the snapshot is supposed to be read-only and the user of the Builder cannot modify the snapshots that it created earlier.
I would recommend this:
An immutable base class:
public class Wibble
{
public string Foo { get; private set; }
public string Bar { get; private set; }
public Wibble(string foo, string bar)
{
this.Foo = foo;
this.Bar = bar
}
}
Then a mutable class which you can change, and then create an immutable copy when the time comes.
public class MutableWibble
{
public string Foo { get; set; }
public string Bar { get; set; }
public Wibble CreateImmutableWibble()
{
return new Wibble(this.Foo, this.Bar);
}
}
I can't remember the C# syntax exactly, but you get the idea.
Further reading: http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx
You cannot make an object immutable!
You can follow this post:
How do I create an immutable Class?
But I think you can always change property values by reflection!
update
"...Actually, string objects are not that
immutable and as far as I know there are at least 2 ways to break string
immutability. With pointers as shown by this code example and with some advanced System.Reflection usage...."
http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/
The other option you have is use the BinaryFormatter to create a memberwise clone of the object to be "locked". Though you're not locking the object you're creating a snapshot which can be discarded while the original remains unchanged.

Categories

Resources