Wednesday, June 10, 2009

TECHNICAL QUESTIONS

Find Table in DB

SELECT *
FROM sys.tables
WHERE name = 'mytable'
AND schema_id = SCHEMA_ID('myschema')

sys.tables contains all the tables. So it would be easier to query sys.tables rather than sys.objects

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TableName]') AND type in (N'U'))


 

Microsoft Videos

http://windowsclient.net/learn/videos.aspx

What is Active Directory?

An active directory is a directory structure used on Microsoft Windows based computers and servers to store information and data about networks and domains


 

http://www.c-sharpcorner.com/Articles/ArticleListing.aspx?SectionID=1&SubSectionID=1

Authenticate a user against the Active Directory
By  Anand Thakur April 05, 2006 

This article serves as a guide to using System.DirectoryServices (SDS) ADSI to access user and group in the Windows Active Directory. Authenticate a user against the Active Directory using the user ID and password.

LDAP, ADSI and SDS

Lightweight Directory Access Protocol (LDAP) is an industry standard directory access protocol (basically set of protocols) for accessing information directories. In Windows, LDAP is the primary way the Operating System accesses the Active Directory database. Active Directory is the information hub of the WindowsServer operating system and index all the data in their entries, and "filters" may be used to select just the person or group you want, and return just the information you want. Active Directory enables centralized, secure management of an entire network and promises to support a single unified view of all objects (such as user accounts, groups, computers and sites) on a network and locating and managing resources faster and easier.

Active Directory Service Interfaces (ADSI) is a COM-based programmatic interface for Microsoft WindowsActive Directory that allows you to create custom scripts to administer Active Directory. ADSI-enabled scripts are capable of performing a wide range of administrative tasks involving Active Directory. Active Directory administration involves managing the life cycle of directory objects from initial creation, modification, searching to deletion.

In the .NET Framework, System.DirectoryServices (SDS) is a namespace that provides simple programming access to LDAP directories such as Active Directory from managed code. System.DirectoryServices is built on the Active Directory Service Interfaces (ADSI) API.

User's login using SDS (ADSI) and Database

Authenticate a user against the Active Directory using the user ID and password. When a user wants to login to your software, he can login using network user/pass provided to him by network administrator. You need not implement and maintain the custom implementation for user/pass using database table. You can simply check for windows users using SDS (ADSI) and validate the entered user/pass against the windows domain. You can even set the permission that user should also belong to particular group in order to access the software.

In the example shown here both types of login are used, one using the simple database table to maintain username/password and second, using Windows domain user by SDS ADSI.

 

Login Using Active Directory Services (SDS)

In order to use SDS, first we have to set properties of LDAP server. Here database ADSI_PARAMETER table is used to set the LDAP properties.

CREATE TABLE [dbo].[ADSI_PARAMETER] (
 [ParameterName] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
 [ParameterValue] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL 
) ON [PRIMARY]
GO

Enter following data to table in ParameterName and ParameterValue fields

Parameter Name

ParameterValue

ServerName

WindowsDomainServer

BaseDN

DC=DomainName,DC=COM

UserDN

OU=Users

GroupName

CN=Operater, OU=Groups

AccountFilter

sAMAccountName

Where ServerName is your domain server machine name. BaseDN is your domain name, most of the time it is company name. UserDN is organizational unit where user should exist. GroupName is organizational unit, to which user should belong in order to access your software. AccountFilter is filter for account name; mostly it is sAMAccountName in windows.

Now we have set the parameter for LDAP server, when the user submit the user/pass from login dialog box with ADSI option. We will pick up the LDAP parameters from database and search the data against parameters and user/pass.

Code for submit button click event. Declare a form level variable int i=0.

private void btnSubmit_Click(object sender, System.EventArgs e)

{

          if(txtUserName.Text.Trim().Equals("") || txtPassword.Text.Trim().Equals(""))

          {

                   MessageBox.Show("Please Enter UserName/Password...");

                   txtPassword.Text="";

                   txtUserName.Text="";

          }

          else

          {

                   //if ADSI radio box is selected call ADSI Login else call simple database login

                   if(rdoADSI.Checked==true)

                   {

                             GetADSILogin();

                   }

                   else

                   {

                             GetDatabaseLogin();

                   }

          }

}

Code for GetADSILogin function. You need to set reference to System.DirectoryService through add reference dialog box in order to use SDS.

public void GetADSILogin()

{

          try

          {

                   string strServerName = "";

                   string strBaseDN = "" ;      

                   string strUserDN = "";

                   string strGroupName = "";

                   string strAccountFilter = "";

                   //Port no for LDAP Default is 389

                   string strPortNo = "389";

                   Boolean blnGroupUser=false;

                   //Data source string

                   string source = "Data Source=ATHAKUR;Initial Catalog=Times;user=sa;password=sa" ;

                   //SQL statement that will be issued

                   string select = "SELECT * from ADSI_PARAMETER";

                   //SQL Connection

                   SqlConnection conn=new SqlConnection(source);

                   // Open the database connection

                   conn.Open () ;

                   // Create the SQL command...

                   SqlCommand cmd = new SqlCommand ( select , conn ) ;

                   //Execute Data reader

                   SqlDataReader myReader = cmd.ExecuteReader();

                   //Check if any rows return against user/pass

                   if(myReader.HasRows)

                   {

                             while(myReader.Read())

                             {

                                      //Store the parameter's data in variables

                                      string strParameterName = myReader.GetString(0).Trim();

                                      string strParameterValue = myReader.GetString(1).Trim();

 
 

if(strParameterName.ToUpper().Equals("SERVERNAME"))

strServerName=strParameterValue; 

if(strParameterName.ToUpper().Equals("BASEDN"))

strBaseDN=strParameterValue;

if(strParameterName.ToUpper().Equals("USERDN"))

strUserDN=strParameterValue;

if(strParameterName.ToUpper().Equals("GROUPNAME"))

strGroupName=strParameterValue;

if(strParameterName.ToUpper().Equals("ACCOUNTFILTER"))

strAccountFilter=strParameterValue;

                             }

                   }

                   //Search for user

                   DirectoryEntry deSystem = new DirectoryEntry("LDAP://" + strServerName + "/" + strUserDN + "," 
                                                       + strBaseDN);

                   deSystem.AuthenticationType=AuthenticationTypes.Secure;

                   deSystem.Username=txtUserName.Text;

                   deSystem.Password =txtPassword.Text;

                   //Search for account name

                   string strSearch=strAccountFilter + "=" + txtUserName.Text;

                   DirectorySearcher dsSystem = new DirectorySearcher(deSystem,strSearch);

                   //Search subtree of UserDN

                   dsSystem.SearchScope= SearchScope.Subtree;

                   //Find the user data

                   SearchResult srSystem = dsSystem.FindOne();

                   //Pick up the user group belong to

                   ResultPropertyValueCollection valcol = srSystem.Properties["memberOf"];

                   if(valcol.Count>0)

                   {

                             foreach( object o in valcol )

                             {

                                      //check user exist in Group we are searching for

                                       if(o.ToString().Equals(strGroupName+","+strBaseDN))

                                      {

                                                blnGroupUser=true;

                                                break;

                                      }

                             }

                   }

                   if(blnGroupUser==true)

                             MessageBox.Show("Login Sucessfull...");

                   else

                             MessageBox.Show("User Does Not Belong to Specified ADSI Group");

          }

          catch(Exception ex)

          {

                    MessageBox.Show(ex.Message);

          }

          i=i+1;

          if(i==5)

          {

                    MessageBox.Show("Login failed for 5 times. Quiting...");

                    this.Close();

}

}

If everything works fine then you will get the message "Login Successful". If user does not belong to group specified in LDAP properties then will the message "User Does Not Belong to Specified ADSI Group". If you enter wrong user/pass, you will get Logon failure message.

Login Using Simple Database Table

You can also give the permission to the user, who are not domains user and wants to use your software. For this we can simply use traditional database LOGIN table.

CREATE TABLE [dbo].[LOGIN] (
 [USERNAME] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
 [PASSWORD] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL 
) ON [PRIMARY]
GO

And admin can enter the username/password in table. And when user selects simple database login option from Login dialog, we can simply check against LOGIN table.

Code for GeDatabaseLogin function.

public void GetDatabaseLogin()

{

          //Data source string

          string source = "Data Source=ATHAKUR;Initial Catalog=Times;user=sa;password=sa" ;

          //SQL statement that will be issued

          string select = "SELECT * from LOGIN where USERNAME='" + txtUserName.Text + "'And PASSWORD 
                               COLLATE Latin1_General_CS_AS='" + txtPassword.Text + "'";

          //SQL Connection

          SqlConnection conn=new SqlConnection(source);

          // Open the database connection

          conn.Open () ;

          // Create the SQL command...

          SqlCommand cmd = new SqlCommand ( select , conn ) ;

          //Execute Data reader

          SqlDataReader myReader = cmd.ExecuteReader();

          //Check if any rows return against user/pass

          if(myReader.HasRows)

                   MessageBox.Show("Login Sucessfull");

          else

                   MessageBox.Show("Login Failed");

                    //Close datareader and connection

                    myReader.Close();

                   conn.Close () ;

                   //check for % attempts

                   i=i+1;

                   if(i==5)

                   {

                             MessageBox.Show("Login failed for 5 times. Quiting...");

                             this.Close();

                   }

}

If user/pass does exist in database then you will get the message "Login successful", otherwise "Login failed" message will be displayed.

Conclusion

We have seen here, how System.DirectoryServices searches the LDAP directory for a user object and validate that against groups. One single domain login user/pass can be used to access the your software. And how SDS manages resources under Windows Active Directory Services.

Aah! Another bug! Well, it's the life.


 

Wednesday, February 4, 2009

Tuesday, January 27, 2009

INTERFACES

INTERFACES
* interfaces can also define events, patameterless properties, and parameterful properties(indexers in C#)
* CLR allows an interface to contain static methods, static fields, constants and static constructors but CLS doesnt allow
* C# prevents an interface from defining any static members.
* CLR doesnt allow an interface to contain any instance fields or instance constructors.

Definitions of 4 interfaces that are defined in the .NET Framework Class Library(FCL)
* IComparable
* Defines a generalized type-specific comparison method that a value type or class implements to order or sort its instances.
* The instance's IComparable implementation is called automatically by methods such as Array.Sort and ArrayList.Sort.

Public interface System.IComparable{
int32 CompareTo(Object object);
}

public class Temperature : IComparable
{
// The temperature value
protected double temperatureF;

public int CompareTo(object obj)
{
if (obj is Temperature)
{
Temperature otherTemperature = (Temperature)obj;
return this.temperatureF.CompareTo(otherTemperature.temperatureF);
}
else
{
throw new ArgumentException("Object is not a Temperature");
}
}

public double Fahrenheit
{
get
{
return this.temperatureF;
}
set
{
this.temperatureF = value;
}
}

public double Celsius
{
get
{
return (this.temperatureF - 32) * (5 / 9);
}
set
{
this.temperatureF = (value * 9 / 5) + 32;
}
}
}

public class CompareTemperatures
{
public static void Main()
{
ArrayList temperatures = new ArrayList();
// Initialize random number generator.
Random rnd = new Random();

// Generate 10 temperatures between 0 and 100 randomly.
for (int ctr = 1; ctr <= 10; ctr++)
{
int degrees = rnd.Next(0, 100);
Temperature temp = new Temperature();
temp.Fahrenheit = degrees;
temperatures.Add(temp);
}

// Sort ArrayList.
temperatures.Sort();

foreach (Temperature temp in temperatures)
Console.WriteLine(temp.Fahrenheit);
Console.Read();

}
}



* IEnumerable
* Exposes the enumerator, which supports a simple iteration over a non-generic collection.
public interface System.collections.IEnumerable{
IEnumerator GetEnumerator();
}

public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}

public string firstName;
public string lastName;
}

public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];

for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return new PeopleEnum(_people);
}
}

public class PeopleEnum : IEnumerator
{
public Person[] _people;

// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;

public PeopleEnum(Person[] list)
{
_people = list;
}

public bool MoveNext()
{
position++;
return (position < _people.Length);
}

public void Reset()
{
position = -1;
}

public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}

class App
{
static void Main()
{
Person[] peopleArray = new Person[3]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
};

People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

}
}

* This code produces output similar to the following:
*
* John Smith
* Jim Johnson
* Sue Rabon
*
*

* IEnumerator
* IEnumerator is the base interface for all nongeneric enumerators.
* The foreach statement of the C# language (for each in Visual Basic) hides the complexity of the enumerators
* Initially, the enumerator is positioned before the first element in the collection. The Reset method also brings the enumerator back to this position. At this position, calling the Current property throws an exception. Therefore, you must call the MoveNext method to advance the enumerator to the first element of the collection before reading the value of Current.
Public interface System.Collections.IEnumerator{
Boolean MoveNext();
void Reset();
Object Current{get;} //Read-only property
}

* ICollection
* Defines size, enumerators and synchronization methods for all collections.
* The ICollection interface is the base interface for classes in the System.Collections namespace.
* The ICollection interface extends IEnumerable;
* IDictionary and IList are more specialized interfaces that extend ICollection.
* An IDictionary implementation is a collection of key/value pairs, like the Hashtable class.
* An IList implementation is a collection of values and its members can be accessed by index, like the ArrayList class.
* Some collections that limit access to their elements, such as the Queue class and the Stack class, directly implement the ICollection interface.
* If neither the IDictionary interface nor the IList interface meet the requirements of the required collection, derive the new collection class from the ICollection interface instead for more flexibility.


Public interface System.Collections.ICollection : IEnumerable{
void CopyTo(Array, Int32 index); //When implemented by a class, copies the elements of the ICollection to an Array, starting at a particular Array index.
int32 Count {get;} //Read-only property. When implemented by a class, gets the number of elements contained in the ICollection.
Boolean IsSynchronized {get;} // Read only property. When implemented by a class, gets a value indicating whether access to the ICollection is synchronized (thread-safe).
Object SyncRoot {get;} // Read - only property. When implemented by a class, gets an object that can be used to synchronize access to the ICollection.

* ICloneable
public interface ICloneable{
object Clone()
}


An interface definition can be marked with modifiers - such as public, protechted, internal, and private the same way a class or structure is marked.
* Nonstatic members of an interface are always considered public and virtual.
* in C# if you implement an interface methoed in a type and omit the virtual keyword, the method is considered virtual and sealed - a type derived from the implementing type cant override the method.
* Like Reference type, a value type can implement zero, or more interfaces. However when you cast an instance of a value type to an interface type, the value type instance must be boxed. because they are ref types.


* IS-A - referes to specialization to generalization relationship. Car is four wheeler.
* if a derived type cant claim an is-a relationship with the base type, then dont use a base type;use an interface
* interfaces imply a CAN-DO relationship. if the CAN-DO functionality feels like it belons with various object types, use an interface.

IS-A-base class eg.
* System.IO.Stream class is an abstract base class. It Provides a bunch of methods, such as Read and Write.
* System.IO.FileStream, System.IO.MemoryStream and System.Net.Sockets.NetworkStream - are derived from Stream.
* Derived class need to implement only synchronous I/O operations; they innherit the ability to perform asynchronous I/O operations from the Stream base class.
* Button, CheckBoxm, ListBox are all derived from System.Windows.Forms.Control

CAN-DO interface Eg.
* FCL Collections are interface based.
* System.Collections namespace defines several collection related interfaces like IEnumerable, Icollection, IList, IDictionary.
* It has concrete classes like ArrayList, Hashtable, Queue, SortedList that implement combinations of above interfaces.
* Interface is used because the implementations of these various collection classes are radically different from one another.
* Or there isnt a lot of sharable code between an ArrayList, a Hashtable and a Queue.
* But they all maintain a set of elements that can be enumerated and allow addding and removing of elements and so interface is used.
* you have reference to an object whose type implements IList Interface. You can write code to add elements, remove elements, and search for an element without having to know what type of collection your are working with.

When you define an interface method in a type using an interface - qualified name, the method is considered private and cant be called usinga variable that is a refence to the type itself.
* to use the above interface method, you have to cast it to that interface. It cant have a public/private modifier.

Arrays

* Double[,] d= new Double[10,20];
* String[,,] st=new String[10,10,10];
Jagged Arrays
* int[][] i= new int[3][];
* i[0] = new int[5];
* i[1]=new int[2];
* i[2]=new int[4];
for(int k=0;k<i[0].lenght;k++)
* FileStream[,] fs = new FileStream[4,5];
* object[,] ob=fs;
* Stream[,] st= (Stream[]) ob;