DataPortal Exception when calling a NameValueListBase class

DataPortal Exception when calling a NameValueListBase class

Old forum URL: forums.lhotka.net/forums/t/588.aspx


vargasbo posted on Tuesday, July 11, 2006

Here's the issue, I call the following code from an winform application and the other one from a console application.

SicCd is a combobox.
SICCD.DisplayMember = "Description";
SICCD.ValueMember = "ID";
SICCD.DataSource = SicList.GetList();

The problem i'm having is that the method, GetList() errors out in the winform app, but not in the console app. Why would that be? I'm thinking it's a security issue, but not really sure, since i don't see all the regular symptoms of it...ideas?

Stack Trace
at OM.OMConfiguration.ConfigInfo.GetConfigValue(String ConfigType, String ConfigCode)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Insights
[Serializable()]
public class BaseNameValue { ....}

[Serializable()] public class SicDomain : BaseNameValue
{ private string active = "N";
public string Active
{ set { active = value; } get { return active; } } }


[Serializable()]
    public class SicList : NameValueListBase<string, SicDomain>
    {
        #region Factory Methods

        private static SicList _list;

        /// <summary>
        /// Returns a list of SicDomain objects.
        /// </summary>
        public static SicList GetList()
        {
            if (_list == null)
                _list = DataPortal.Fetch<SicList>(new Criteria(typeof(SicList)));
            return _list;
        }

        /// <summary>
        /// Clears the in-memory SicList cache
        /// so the list of roles is reloaded on
        /// next request.
        /// </summary>
        public static void InvalidateCache()
        {
            _list = null;
        }

        private SicList()
        { /* require use of factory methods */ }

        #endregion

        #region Data Access
        private Database _dataBase;
        protected Database Database
        {
            get
            {
                if (_dataBase == null)
                    _dataBase = DatabaseFactory.CreateDatabase(DatabaseProp.CustInfo);
                return _dataBase;
            }
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        private void DataPortal_Fetch(Criteria criteria)
        {
            try
            {
                this.RaiseListChangedEvents = false;
                //Database db = DatabaseFactory.CreateDatabase(DatabaseProp.CustInfo);
                SafeDataReader DR = new SafeDataReader(this.Database.ExecuteReader("usp_GetSicCodes"));
                IsReadOnly = false;
                while (DR.Read())
                {
                    SicDomain sic = new SicDomain();
                    LoadDomainFields(sic, DR);
                    this.Add(new NameValuePair(sic.ID, sic));
                }
                IsReadOnly = true;

                this.RaiseListChangedEvents = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private static void LoadDomainFields(SicDomain sic, SafeDataReader DR)
        {
            sic.ID = DR.GetString(0).Trim();
            sic.Value = DR.GetString(0).Trim();
            sic.Description = DR.GetString(1).Trim();
        }
        #endregion

    }

DatabaseFactory.CreateDatabase(DatabaseProp.CustInfo) call is our own way of pulling the connection string from an admin table, instead of having to hardcode them in every application, for an enviorment. Database factor will call a com+ objects, which is called ConfigInfo, hence why you see it in the call stack ConfigInfo.GetConfigValue

ajj3085 replied on Tuesday, July 11, 2006

It doesn't sound like a security problem, since you're running off teh same drive and as the same user (I'm assuming anyway).  Something is getting mucked up with the COM interop.. but I'm don't know enough about your COM component to help much beyond that..

Can you post all the exception details, not just the stack trace?  That'd be very helpful.

vargasbo replied on Tuesday, July 11, 2006

You're right, my com+ object doesn't seem to be getting the constructor it needs. The error I get is Object reference not set to an instance of an object. The ConfigInfo com+ object, has a constructor string which is set in component services, it's value is
Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=dbadmin;Data Source=omdbdev01\om
I don't force activation context and open the object up to everyone on my box.

ajj3085 replied on Tuesday, July 11, 2006

You're talking about activation context; is it safe to assume you're running the COM object under MTS?

vargasbo replied on Tuesday, July 11, 2006

Correct.

ajj3085 replied on Tuesday, July 11, 2006

Could MTS be tearing down your COM object?  Is there a security setting where MTS isn't allowed to give your Forms app access to the COM object, but your console app is? 

Also, could you post all the exception details (the Exception + its inner exceptions).

Thanks
Andy

vargasbo replied on Tuesday, July 11, 2006

Alright, the issue was found. Back in my SicList class I had this code....
DatabaseFactory.CreateDatabase(DatabaseProp.CustInfo);

DatabaseProp.CustInfo was pulling from an app.config file, which just return a db name. The problem seems to be that app.config doesn't return the strings b/c of security, or some reason.

Why it works for the console unit test, i'm not to sure.

Copyright (c) Marimer LLC