5
votes

I was previously using static variables to hold variable data that I want to save between postbacks. I was having problems and found that the data in these variables is lost when the appdomain ends. So I did some research and decided to go with ViewStates:

static Dictionary<string, linkButtonObject> linkButtonDictonary;


protected void Page_Load(object sender, EventArgs e)
{
    if (ViewState["linkButtonDictonary"] != null)
    {
        linkButtonDictonary = (Dictionary<string, linkButtonObject>)ViewState["linkButtonDictonary"];
    }
    else
    {
        linkButtonDictonary = new Dictionary<string, linkButtonObject>();
    }
}

And here is the very simple class I use:

[Serializable]
public class linkButtonObject
{
    public string storyNumber { get; set; }
    public string TaskName { get; set; }
}

I am adding to linkButtonDictionary as a gridview is databound:

protected void hoursReportGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        LinkButton btn = (LinkButton)e.Row.FindControl("taskLinkButton");
        linkButtonObject currentRow = new linkButtonObject();
        currentRow.storyNumber = e.Row.Cells[3].Text;
        currentRow.TaskName = e.Row.Cells[5].Text;
        linkButtonDictonary.Add(btn.UniqueID, currentRow);
    }
}

It appears that my previous issues are resolved however a new one has arisin. Sometime when I postback I am getting this error:

[A]System.Collections.Generic.Dictionary2[System.String,linkButtonObject] cannot be cast to [B]System.Collections.Generic.Dictionary2[System.String,linkButtonObject]. Type A originates from 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'LoadNeither' at location 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. Type B originates from 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'LoadNeither' at location 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'.

I don't understand how there can be a casting issue when I am using the same class everywhere. What am I doing wrong and how do I fix it?

2
Somehow you've managed to load the same assembly (mscorlib) in different loading contexts. Are you using Assembly.LoadFrom() or similar to load mscorlib or other components that would load it? - Pete
You might try using the Fusion Log Viewer to track down the issue: msdn.microsoft.com/en-us/library/e74a18c4%28VS.71%29.aspx - Pete
I don't load any assemblies programatically and don't even know what mscorlib is. - David Tunnell
Well, you've somehow managed to do it, possibly indirectly via some library or something. The Fusion Log Viewer should help you out. - Pete
This doesn't answer your question, per se, but you could try putting the object in Session. If you are concerned with appdomain restarts, use the State Server or SQL. - acfrancis

2 Answers

4
votes

Thanks everyone for their input, it helped me track down the problem.

I had my simple class in the .aspx.cs page:

[Serializable]
public class linkButtonObject
{
    public string storyNumber { get; set; }
    public string TaskName { get; set; }
}

This is why assemblies were loading twice and causing the issue.

3
votes

This looks exactly like the following issue:

InvalidCastException when serializing and deserializing

As for the solution, it might be out of your control to handle assembly load etc.

An easy approach is XML Serialize/JSON Serialize your data as string and save that string in ViewState. To obtain it back you just need to reverse the process. This will take care of duplicate load issue for sure.