Search This Blog

Friday, November 22, 2013

How to fix Configuration system failed to initialize

Configuration system failed to initialize- Issue in .NET

Problem : 

I was working on a console application which will work as a Task Scheduler on the server, so I created a console application in Visual Studio 2012, so the project was created with Target Framework as v4.5, but the problem with that was, neither our QA server or Production server for that app had Framework v4.5 installed on them. So what I did was, I went to the project properties and changed the Target Framework to 4.0 instead of 4.5 and tried to run on Debug, thats it, I keep getting the error whenever the application was trying to read configuration values using ConfigurationManager.AppSettings and the error reads as below

"Configuration system failed to initialize".

Solution : 

Like most of us, I copied the exception details and googled it and this is what I got as a probable resolution from Stack overflow.



make sure that your config file (web.config if web, or app.config if windows) in your project starts as:
<?xml version="1.0"?>
<configuration>
   <configSections>
      <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="yourProjectName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>

The above answer and more such similar answers on the internet points to the configSettings section & has been marked as an answer by most people so I guess this has resolved their issues but not in my case. It still gave me the errors. So this is what I did to get it resolved.

If you have an already running Console Application like me lets say in v4.5, then 
1. If that application is open in visual studio make sure its running in the current version, just check-in your changes to source control and close the studio.
2. Open the *.csproject file on notepad and change the targetFramework from 4.5 to 4.0 like this 
"<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>" and save the file.
3. Open the project now on visual studio and go to App.config file and make the change in the file under element startup and make .NETFramework, Version=v4.0 like below

<startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>

Now if you run your application, it should run just fine, atleast in my case.


Wednesday, November 20, 2013

Unable to Resolve Service Name, Oracle connection from ASP.NET or SSIS Business Intelligence Studio

Unable to Resolve Service Name, Oracle connection from ASP.NET or SSIS Business Intelligence Studio

Problem

In one of my recent projects, I had this peculiar problem where I was not able to connect to Oracle Database from my ASP.NET application and every time it gave me an error like "Unable to resolve service name", although my tnsnames.ora file was correct and moreover, I was able to connect to the same oracle datasource from the Oracle SQL Developer studio, it was just driving me crazy.

Solution

One quick solution I figured out for both my connecting to oracle from the BIDS and Microsoft Visual Studio web configuration like below

Lets say your tnsnames.ora reads like below

oradb.mydomain.com =
(DESCRIPTION =
  (ADDRESS = (PROTOCOL = TCP)(HOST = host.mydomain.com)(PORT = 1521))
  (LOAD_BALANCE = YES)
  (CONNECT_DATA =
   (SERVER = DEDICATED)
   (SERVICE_NAME = oradb.mydomain.com)
   (FAILOVER_MODE =
   (TYPE = SELECT)(METHOD = BASIC)(RETRIES = 180)(DELAY = 5)
   )
  )
)

This is what has to be done when putting the connection string inside Visual Studio to get it connected to the oracle database.

<connectionStrings>
<add name="myConn" connectionString="Server=host.mydomain.com/oradb.mydomain.com; User Id=guest; Password=guest" providerName="System.Data.OracleClient" />

So above all that I did was to mention the host name along with the service name. Mind you, there is one important thing here, the oracle data source is running on the default port 1521.

The problem associated with connecting to Oracle datasource using an OLEDBDatsource control on BIDS is slightly more than just the connection to the oracle datasource if you are working on a 64 bit machine/PC. The BIDS is a 32 bit application and so you have to make sure that you have a 32 bit oracle client installed on your PC along with the 64 client of Oracle otherwise the BIDS may not be able to detect the "Oracle Provider for OLE DB" driver from the PC that you are working on. 

Once this is resolved, like the visual studio, here also we will mention the DataSource in the connection string as host/service_name in the connection used as shown in the screen shot shown below.

In the connection manager above, the Server or file name is mentioned as "host.mydomain.com/oradb.mydomain.com". But here also please note that in my case the oracle datasource was running on default port 1521. 

Thants it ! Happy coding !

Tuesday, November 5, 2013

Reading XML nodes with namespaces in SQL Server

Reading XML nodes with namespaces in SQL Server


Like me, many of you might have gone through situations where you might had to parse and read XML in SQL Server. SQL Server 2005 onward have a very good functional support to read XML. Lets go over some examples on how to do so 

1. The first XML is an xml with persons details and contact details and here is how we can read that below

DECLARE @MyXML XML
SET @MyXML = '<SampleXML>
<Person>
<firstName>Kaushik</firstName>
<lastName>Ghosh</lastName>
<skill>ASP.NET</skill>
<language montherTongue="Bengali">Hindi</language>
<age>31</age>
</Person>
<Contacts>
<primaryEmail>primary@mydomain.com</primaryEmail>
<secondaryEmail>secondary@mydomain.com</secondaryEmail>
<primaryPhone>1234567890</primaryPhone>
<secondaryPhone>Melon</secondaryPhone>
</Contacts>
</SampleXML>'

SELECT
a.b.value('Person[1]/firstName[1]','varchar(10)') AS firstName,
a.b.value('Person[1]/lastName[1]','varchar(10)') AS lastName,
a.b.value('Person[1]/skill[1]','varchar(10)') AS skill,
a.b.value('Person[1]/language[1]/@montherTongue','varchar(10)')+ ',' + a.b.value('Person[1]/language[1]','varchar(10)') AS language,
a.b.value('Person[1]/age[1]','varchar(10)') AS age,
a.b.value('Contacts[1]/primaryEmail[1]','varchar(30)') AS primaryEmail,
a.b.value('Contacts[1]/secondaryEmail[1]','varchar(30)') AS secondaryEmail,
a.b.value('Contacts[1]/primaryPhone[1]', 'varchar(10)') AS primaryPhone,
a.b.value('Contacts[1]/secondaryPhone[1]', 'varchar(10)') AS secondaryPhone
FROM @MyXML.nodes('SampleXML') a(b)

In the above example it works fine, when the nodes are not repeating, but what if the XML has repeating nodes, please see the next example. This time we will take an example which will have namespaces, nested nodes with attributes and also multiple repeating nodes.

DECLARE @xml_text xml;
SET @xml_text = '
<towers xmlns="http://www.mydomain.org/schemas/xmls" version="1.4.1.0">
<tower xmlns="http://www.mydomain.org/schemas/xmls" uid="2183256">
<name>J.D. TAYLOR 24 #1</name>
<numAPI>0100320139</numAPI>
<towerLocation uid="Location1">
<latitude uom="dega">20.329705810</latitude>
<longitude uom="dega">-27.720651970</longitude>
</towerLocation>
<towerDatum uid="GL">
<code>GL</code>
<name>Ground Level</name>
</towerDatum>
<operator>Mobile comp1</operator>
<country>Unknown</country>
<county>DuPage</county>
<state>Illinois</state>
<timeZone>-00:00</timeZone>
<commonData>
<dTimCreation>2013-10-04T18:51:09.377</dTimCreation>
<dTimLastChange>2013-10-04T18:51:09.377</dTimLastChange>
</commonData>
</tower>
<tower xmlns="http://www.mydomain.org/schemas/xmls" uid="2183256">
<name>K.D. TAYLOR 24 #1</name>
<numAPI>0100320140</numAPI>
<towerLocation uid="Location2">
<latitude uom="dega">10.329705811</latitude>
<longitude uom="dega">-17.720651970</longitude>
</towerLocation>
<towerDatum uid="SL">
<code>SL</code>
<name>Sea Level</name>
</towerDatum>
<operator>Mobile Company 2</operator>
<country>Unknown</country>
<county>Cook</county>
<state>ILLINOIS</state>
<timeZone>-00:00</timeZone>
<commonData>
<dTimCreation>2013-11-04T18:51:09.377</dTimCreation>
<dTimLastChange>2013-11-04T18:51:09.377</dTimLastChange>
</commonData>
</tower>
</towers>';

with xmlnamespaces('http://www.mydomain.org/schemas/xmls' as towers,
default 'http://www.mydomain.org/schemas/xmls')
    SELECT  T.Item.value('(name/text())[1]', 'varchar(200)') as name,
T.Item.value('(numAPI/text())[1]', 'varchar(30)') as numAPI,
T.Item.value('towerLocation[1]/@uid[1]', 'varchar(20)') as towerLocation,
T.Item.value('towerLocation[1]/latitude[1]', 'varchar(20)') + ' ' 
+ T.Item.value('towerLocation[1]/latitude[1]/@uom[1]', 'varchar(10)') as latitude,
T.Item.value('towerLocation[1]/longitude[1]', 'varchar(20)') + ' ' 
+ T.Item.value('towerLocation[1]/longitude[1]/@uom[1]', 'varchar(10)') as longitude,
T.Item.value('towerDatum[1]/@uid[1]', 'varchar(10)') as towerDatumCode,
T.Item.value('towerDatum[1]/code[1]', 'varchar(10)') + ' or ' 
+ T.Item.value('towerDatum[1]/name[1]', 'varchar(20)') as towerDatum,
T.Item.value('(operator/text())[1]', 'varchar(200)') as operator,
T.Item.value('(country/text())[1]', 'varchar(30)') as country,
T.Item.value('(county/text())[1]', 'varchar(30)') as county,
T.Item.value('(state/text())[1]', 'varchar(30)') as state,
T.Item.value('(timeZone/text())[1]', 'varchar(30)') as timeZone,
T.Item.value('commonData[1]/dTimCreation[1]', 'varchar(30)') as created,
T.Item.value('commonData[1]/dTimLastChange[1]', 'varchar(30)') as changed
    FROM    @xml_text.nodes ( 'towers/tower' ) AS T(item)

The above XML is a more realistic example of XML data that you might need to parse in the database while doing some sort of integration.

Thursday, October 3, 2013

Saving & retrieving/updating data using cookies

Saving & retrieving/updating data using cookies.

Like me, I believe most of you might had to use cookies in one way or the other, in my case, I had the following scenario. In a website, the user logs in who has access to numerous retail brands and every time he/she works with only one particular brand and this particular brand in which he/she works most has to be set as a preferred brand. So when the user is done with his/her work and closes the session, the last chosen brand has to be persisted and that has to be his/her preferred brand.

So going by the requirement, the most simple and quick resolution will seem to save the preferred brand in cookies of the browser. So the following two functions does exactly that. The get function gets the saved preferred brand when the user first opens the session to the website and the set functions sets a preferred brand when the user switches from one brand to the other. From where you want to call these functions is left abstract as your site may have master pages, or may not have master pages or your pages might be inherited from a Base Page class hence there can be numerous such scenarios.

     /// <summary>
    /// gets the preferred brand for the user from saved cookie.
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    public int getPreferredBrand(string userId)
    {
        int preferredBrandId = 0;
        try
        {
            //1. check to see if cookie exists with preferred brandid.
            //2. if yes then return the preferred brandid.
            HttpCookie authCookie = HttpContext.Current.Request.Cookies[PrefBrandCookieName];
            if (authCookie != null)
            {
                System.Web.Security.FormsAuthenticationTicket ticket = System.Web.Security.FormsAuthentication.Decrypt(authCookie.Value);
                preferredBrandId = int.TryParse(ticket.UserData.ToString(), out preferredBrandId) == true ? preferredBrandId : 0;
            }
            else
                preferredBrandId = 0;
        }
        catch (Exception ex)
        {
            Exception customEx = new Exception("Error while trying to retrieve cookiename<<" + userId + ">>.See detailed exception.." + ex.Message);
            ExceptionManager.Publish(customEx);
        }
        return preferredBrandId;
    }
    /// <summary>
    /// sets preferred brand for the user when session expires or browser is closed.
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="brandId"></param>
    public void setPreferredBrand(string userId, int brandId)
    {
        try
        {
            //1. Check if cookie exists
            System.Web.Security.FormsAuthenticationTicket authTicket = null;
            HttpCookie authCookie = HttpContext.Current.Request.Cookies[PrefBrandCookieName];
            authTicket = new System.Web.Security.FormsAuthenticationTicket(1, userId, DateTime.Now, DateTime.MaxValue, true, brandId.ToString());

            //2. Persist selected brand in cookies.
            //will persist cookie even when the browser is shutdown.
            if (authCookie != null)
                authCookie.Value = System.Web.Security.FormsAuthentication.Encrypt(authTicket);
            else
                authCookie = new HttpCookie(LCoreUser.PrefBrandCookieName, System.Web.Security.FormsAuthentication.Encrypt(authTicket));
            authCookie.Expires = DateTime.MaxValue;
            HttpContext.Current.Response.Cookies.Add(authCookie);
        }
        catch (Exception ex)
        {
            Exception customEx = new Exception("Error while persisting cookie for user<<" + userId + ">> and brand<<" + brandId.ToString() + ">>.See detailed exception.." + ex.Message);
            ExceptionManager.Publish(customEx);
        }
    }

The above code is pretty self explanatory. In the set function, I first check if the cookie does exist or not and if it does, then update the cookie value by assigning a new ticket into it. And if the cookie does not exist then all I do is create a new cookie and assign the ticket value.

Wednesday, September 18, 2013

Oracle connect problems from ASP.NET

Many people like me, might have faced the issue, where even after installing the Oracle client and doing all configurations right inside tnsnames.ora, may not be able to connect to Oracle database.

The Error message might read as "ORA-12154 :TNS:Could not resolve the connect identifier specified".

Here is a quick tip on how to connect. Instead of only mentioning the Service Name or the SID name in the Web.config, mention the entire connection description like below

<add key="OracleConnection" value="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host)(PORT=1521)))(CONNECT_DATA=(SID=oradev))); User Id=user_id; Password=password"/>

* The above method will definitely work if you are able to connect to your Oracle database using Oracle Net Configuration.

Friday, August 23, 2013

Granting permission to a particular on Db schema (SQL Server)

There might be scenarios where you might move the code to QA or production and then grant access to user setup for the Application's access. Here is how you can do it as shown below

USE DBName
GO

GRANT EXECUTE ON SCHEMA :: schemaName TO App_User;

The highlighted in bold options are the inputs that will depend on the database name of your application, the schema whose objects you need to access and the user setup for application's access.

Wednesday, August 21, 2013

Querying Active Directory using LDAP by LDAPBrowser and C#

Insight into Problem

There may be projects/project work where you might have to lookup the user on Active Directory using some LDAP tool or querying the domain controller to see how the user has been setup without making any modifications as such. Adding to that, there might be scenarios where you might have to get user details from Active Directory for the purpose of impersonating the user in the application for the sake of troubleshooting.

Looking up users on LDAP using Tool

For looking up a user on Active Directory or Novell using a tool can be done easily using a tool like LdapBrowser and the way the tool binds user information can lay the foundation of a C# application which can do the same, if we need the user to be impersonated for troubleshooting purposes.

After installing the LDAP Browser and setting up the profile, please refer to link on how to do so and get the browser software, here we are not going into the details of that but a typical user search on directory will have the parameters and result screen as follows.

Search DN: DC=mycomp,DC=com; Filter: (cn=*kaushik*)

Whats important in the above screen shot is the Filter Text and the DN value, we are going to use similar parameters while doing it through C# application. Please look at another search below, where we use the user's id and also specify which properties to load in the search result. If you are using the Active Directory, then the userid is usually within the attribute "sAMAccountName" and on Novell its called uid. I think it depends on how the Domain Administrators set it up.

So the parameters I have put in are below
1. Search DN: DC=mycomp,DC=com
2. Filter: (sAMAccountName=myuid), here "myuid" is the id that you need to search on domain controller.
3. Attributes : cn,mail, sAMAccountName. (These are the attributes that I ask to be loaded in the Search Result).



In the above result screen, not only have we specified a more specific filter but also mentioned what attributes need to be leaded in the search result. Having fairly an idea of how things work, we are going to quickly move on to the next section and see how to do the same operations using C# application without using any third party tools.

Querying Active Directory using LDAP/C# application

The following method "searchUser", searches the LDAP based on 2 different inputs, one is the search text and the other is the searchby. The searchby specifies weather the search will done by user's name (cn), or user's id (sAMAccountName) or user's email (mail). Based on the searchBy parameter passed to the function, the filterText gets created by calling the getFilterText function, please look at the implementation in the next section along with the declaration of the LDAPUser class.

/// Searches input text on LDAP to get users
        /// </summary>
        /// <param name="searchText"></param>
        /// <param name="searchBy"></param>
        /// <returns></returns>
        public List<LDAPUser> searchUser(string searchText, string searchBy)
        {
            List<LDAPUser> result = new List<LDAPUser>();
            try
            {
                DirectoryEntry entry = new DirectoryEntry(_ldapUrl);
                DirectorySearcher mySearcher = new DirectorySearcher(entry);
                string[] propertiesToLoad = { "cn, mail, memberOf, sAMAccountName" };
                mySearcher.PropertiesToLoad.AddRange(propertiesToLoad);
                mySearcher.Filter = (getFilterText(searchText, searchBy));
                mySearcher.SearchScope = SearchScope.Subtree;
                mySearcher.ServerTimeLimit = new TimeSpan(0, 0, 60);
                mySearcher.ClientTimeout = new TimeSpan(0, 10, 0);

                foreach (System.DirectoryServices.SearchResult resEnt in mySearcher.FindAll())
                {

                    System.DirectoryServices.DirectoryEntry de = resEnt.GetDirectoryEntry();
                    LDAPUser entity;
                    if (de.Properties["sAMAccountName"].Value != null && de.Properties["mail"].Value != null)
                    {
                        entity = new LDAPUser
                        {
                            UserId = de.Properties["sAMAccountName"].Value.ToString(),
                            Email = de.Properties["mail"].Value.ToString(),
                            Name = de.Properties["cn"].Value.ToString(),
                            LdapBinderUserId = BinderUserId,
                            LdapBinderPassword = BinderPassword
                        };
                        result.Add(entity);
                    }

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

Below is the implementation of the filter text that we need to pass to the DirectorySearcher and also the LDAPUser class declaration along with the LDAP Url that you will need to save/pass.

private string getFilterText(string searchText, string searchBy)
        {
            string result = string.Empty;
            try
            {
                switch (searchBy.ToLower())
                {
                    case "userid":
                        result = "(sAMAccountName=" + searchText + ")";
                        break;
                    case "email":
                        result = "(mail=" + searchText + ")";
                        break;
                    default:
                        result = "(cn=*" + searchText + "*)";
                        break;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }


The LDAP User class looks as below

public class LDAPUser
    {
        public long Id { getset; }
        public string Name { getset; }
        public string UserId { getset; }
        public string Email { getset; }
        
    }

The LDAP Url can be declared in configuration file or can be saved somewhere else. This url is required to be passed to the constructor DirectoryEntry before the search.

<add key="LDAPUrl" value="LDAP://mycomp.com:389/DC=mycomp,DC=com"/>

That is pretty much how you can search and get users from Active Directory using LDAP/ C#. I hope this helps.