5

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?

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
David Tunnell
  • 7,252
  • 20
  • 66
  • 124
  • 1
    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 Oct 31 '13 at 21:22
  • 1
    You might try using the Fusion Log Viewer to track down the issue: http://msdn.microsoft.com/en-us/library/e74a18c4%28VS.71%29.aspx – Pete Oct 31 '13 at 21:23
  • I don't load any assemblies programatically and don't even know what mscorlib is. – David Tunnell Oct 31 '13 at 21:26
  • Well, you've somehow managed to do it, possibly indirectly via some library or something. The Fusion Log Viewer should help you out. – Pete Oct 31 '13 at 21:27
  • 1
    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 Oct 31 '13 at 21:32

2 Answers2

4

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.

David Tunnell
  • 7,252
  • 20
  • 66
  • 124
3

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.

Community
  • 1
  • 1
Abhinav
  • 2,085
  • 1
  • 18
  • 31