NetSqlAzManWebConsole\dlgItemProperties.aspx.cs always has a null db value

Jul 11, 2009 at 2:25 AM

Release When 3.6.0.1

When running NetSqlAzManWebConsole under our own applications web solution, as referenced project. Navigation works fine untill we try to view a item or storagegroups properties.   

with a Item selected (does not matter what type) ,

selecting the [item] Properties from the Action panel,

the item loaded in the dialog NetSqlAzManWebConsole\dlgItemProperties.aspx.cs always has a null db value (internal NetSqlAzManStorageDataContext db;) is always null, and i get null object exceptions.

The same thing occurs for StorageGroups, db is null;

We would appreciate it if you have an idea why this may be happening. 

Thankyou

Bryan   

Jul 11, 2009 at 8:06 AM

Hi,

It could be a serialization problem.

When calling the dlgItemProperties.aspx page the item you want to see has requested that is a Session variable.

Line 69: this.item = (IAzManItem) this.Session [ "selectedObject"];

In your case ... what kind of session are you using ?

InProc, SQL Server and State Server?

Let me know.

Regards,

Andrea.

__________________________________
Andrea Ferendeles
NetSqlAzMan - Project Coordinator

http://netsqlazman.codeplex.com

Jul 13, 2009 at 6:08 PM

Yes, we are using Sql for session. I note NetSqlAzManStorageDataContext db is marked non-serializable , so I assume I will have to re-construct that on each request. 

Unfortunately , using Sql for session cannot be changed.  

Regards,

Bryan 

Jul 13, 2009 at 9:35 PM

Got passed the Db null changes by recreating them in Session members from Global Application_PreRequestHandlerExecute.

However now have a problem with System.Windows.Forms.ListView not being serilizable, is there anything specific that requires use of 'System.Windows.Forms.ListView' in WebConsole. As this is non-serilizable, we are now getting session serilization exceptions from lsvRoles lsvTasks and lsvOperations being held is session.

It looks like I would also need to replace these with another container of some sort.  

 

Regards

Bryan

Jul 14, 2009 at 2:28 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jul 14, 2009 at 2:35 PM

Hi,

I have checked-in now the 3.6.0.3 beta (Core & Web Console) that fix this issue.

I have replaced the System.Windows.Forms.ListView class with a custom serializable ListView class.

Please download the latest WebConsole source code version and use this code fragment into the Gloabal.asax to fix the DataContext Serialization issue for all NetSqlAzMan objects (thought Reflection):

  protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)

        {

            //Uncomment this to enable State Session

            if (this.Session["storage"] != null)

            {

                string storageConnectionString = ((SqlAzManStorage)this.Session["storage"]).ConnectionString;

                NetSqlAzMan.LINQ.NetSqlAzManStorageDataContext dc = new NetSqlAzMan.LINQ.NetSqlAzManStorageDataContext(storageConnectionString);

                for (int i = 0; i < this.Session.Keys.Count; i++)

                {

                    string sessioneKey = this.Session.Keys[i];

                    object sessionOject = this.Session[sessioneKey];

                    if (sessionOject != null)

                    {

                        this.setDataContext(sessionOject, dc);

                    }

                }

            }

        }

        private void setDataContext(object o, object dc)

        {

            if (o != null)

            {

                FieldInfo fi = o.GetType().GetField("db", BindingFlags.NonPublic | BindingFlags.Instance);

                if (fi != null && fi.GetValue(o) == null)

                {

                    fi.SetValue(o, dc);

                    var subFields = o.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

                    foreach (var subField in subFields)

                    {

                        object subO = subField.GetValue(o);

                        this.setDataContext(subO, dc);

                    }

                }

            }

        }

Regards,

Andrea.

__________________________________
Andrea Ferendeles
NetSqlAzMan - Project Coordinator

http://netsqlazman.codeplex.com

Jul 14, 2009 at 2:52 PM
This is great. I had done something similar in my custom changes , although not as elegant. I will download 3.6.0.3 code and test.   
Regards
Bryan
Jul 17, 2009 at 8:42 PM
Edited Jul 20, 2009 at 1:16 PM

 

Hi Andrea,

Just one change is needed in 

Global Application_PreRequestHandlerExecute

You need to test that the Current Handler has a Session to avoid occasional Exceptions.

if ((Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState) && (this.Session["storage"] != null))

 

Regards

Bryan

Jul 17, 2009 at 9:00 PM

Also , NetSqlAzManWebConsole.ADObject needs to be marked Serializable

Jul 21, 2009 at 8:44 AM

I will do it for the next release.

TY.

Andrea.

Jul 21, 2009 at 8:45 AM

Well done.

Jul 21, 2009 at 8:47 AM

… and ADObjectState too. J

Jul 22, 2009 at 2:16 AM
Edited Jul 22, 2009 at 2:19 AM

sorry to give you this feed back in little bits at a time, but I am not able to test for any length of time without interuption.

Two more changes ,

1) another serialization error

in ADObject set internalSid nonserializabed

[NonSerialized]

internal SecurityIdentifier internalSid = null;

becuase you reconstruct in get Sid its fine to not be passed back in Session.

2)  In \NetSqlAzManWebConsole\ADObjectPickerShowDialog.aspx.cs

Wrap the inititial AD search in try - catch to avoid AD domain not accessable Exception ending search  

private

ADObject resolveName(string name)

.......           

SearchResultCollection results = null;
            ADObject ado = new ADObject();
            try
            {
                results = deSearch.FindAll();
                //Try find exactly
                if (results.Count == 1)
                {
                    DirectoryEntry de = results[0].GetDirectoryEntry();
                    ado.Name = (string)de.InvokeGet("samaccountname");
                    ado.ADSPath = de.Path;
                    ado.UPN = (string)de.InvokeGet("userPrincipalName");
                    ado.internalSid = new SecurityIdentifier((byte[])de.Properties["objectSid"][0], 0);
                    ado.state = ADObjectState.Resolved;
                    return ado;
                }

                //Then try find with jolly (*)
                if (this.adObjectType == ADObjectType.UsersOnly || this.adObjectType == ADObjectType.OneUserOnly)
                {
                    deSearch.Filter = String.Format("(&(|(displayName=*{0}*)(samaccountname=*{0}*)(userprincipalname=*{0}*))(&(objectClass=user)(objectCategory=person)))", name);
                }
                else if (this.adObjectType == ADObjectType.UsersAndGroups)
                {
                    deSearch.Filter = String.Format("(&(|(displayName=*{0}*)(samaccountname=*{0}*)(userprincipalname=*{0}*))(|(&(objectClass=user)(objectCategory=person))(objectClass=group)))", name);
                }
                results = deSearch.FindAll();
            }
            catch ()
            {
              // Give up on directory Services search  
            }

            if (results == null || results.Count == 0)
            {

-----------

regards Bryan

 

Jul 23, 2009 at 8:35 AM
Edited Jul 23, 2009 at 12:52 PM

1) OK

2) I have not Understood .. explain better … plz.

 

Jul 23, 2009 at 2:57 PM

in resolveName(string name) , our corporate policy disallows some AD access in some cases, so the call to deSearch.FindAll(); will get a access denied exception. By catchting and discarding the execption, the later direct domain lookup can contine and succeed. 

Bryan

    

Jul 24, 2009 at 10:54 PM

Ok.

You have right.

Will be done for the next release.

TY.

Andrea.

__________________________________
Andrea Ferendeles
NetSqlAzMan - Project Coordinator

http://netsqlazman.codeplex.com