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;

Friday, December 19, 2008

Enum and bit flag

Enum
enum Color{
red, //0
blue, //1
orange, //3
}

Instead of hardcoding the numbers..use enum.
* symbolic name is used throughout the code, just change the number and recompile when ever necessary
* enumeration are strongly types..cant pass orange instead of wood.
* cant define an methods, properties or events.
* after compilation, each symbol is replaced by a constant field.
* enumerated type is just a structure that has a bunch of constant fields defined in it.
* After compilation, assembly that defined the enumerated type doesnt have to available at run time.
* fields can be byte, sbyte, short, ushort, uint,long, or ulong..int is default.

enum Color : byte{
Red,
Green,
Blue,
}
Console.WriteLine(Enum.GetUnderlyingType(typeof(Color)) ); //system.byte
Color co = Color.Green;
Console.WriteLine(co) //Green
Console.WriteLine(co.ToString()) //Green
Console.WriteLine(co.ToString("D")) 1
Console.WriteLine(Enum.Format(typeof(Color),(Byte)2,"G")); //Blue
Color[] cm = (Color[])Enum.GetValues(typeof(Color));
foreach(Color m in cm)
Console.WriteLine(m);

[Flags] attribute is applied so that a symbol matching each 1 bit islooked up and concatenated to a string; each symbol is separated by comma.


File Flags
* System.IO.File and System.IO.FileAttributes
*
* String fl = @"c:\YServer.txt";
System.IO.FileAttributes at=System.IO.File.GetAttributes(fl);
Console.WriteLine(at);

Text

STRING
* String type is derived immediately from object, making it a reference type.
* Implements several interfaces like Icomparable, Icloneable, Iconvertible, IEnumerable
* primitive type
* immutable - once created, a string can never get longer, get shorter, or have any of its characters changed.
Equals - checks if same object and returns true otherwise checks if all characters are same n return true

STRINGBUILDER
* Internally , a stringbuilder object has a field that refers to an array of char structures.
* performs dynamic operations with strings and characters to create a string.
* convert the stringbuilder's character array into a string by calling tostring. it will return the refernce to string field of stringbuilder
* string returned is immutable.
* attempt to edit stringbuilder after tostring was called will return a new stringbuilder object
* mutable string

Encoding: conversion between characters and bytes
* In CLR, all characters are represented as 16-bit Unicode code values and all strings are composed of 16-bit Unicode code values.
* transmitting 16th bit value isnt very efficient as half of the bytes written would contain zeros.
* Better encode it to compress it in array of bytes..transmit it then again decode back to 16th bit values
* encoding is done for system.IO.binarywriter and streamwriter and decoding is done for system.io.binaryreader or streamreader.
* no encoding then default is UTF-8

Most frequently used encoding are UTF-16 and UTF-8
UTF-16
* encode 16-bit character as 2 bites.
* no compression
* excellent performance
* also known as Unicode Encoding.

UTF-8
* encodes some as 1 byte,2byte,3byte and four byte.
* less useful than UTF-16 when encoding for 4byte is done mostly.

UTF-7
* for characters expressed using 7-bit values.
* rather avoid as its ends with expanding data instead of compressing.

ASCII
* encodes 16 bit characters in ASCII characters.
* any values less than 256 can be converted into single byte
* for greater the value is lost
* compressed data in half

to encode or decode ..create instance of class derived from system.text.encoding.

Comparing Strings
* Equals - calls CompareOrdinal method- check for same ref first then compare the characters.
* CompareOrdinal - checks for same characters.- always case sensitive - fast
* Compare - culture specific - logically equal strings

Delegates and Events

DELEGATES
* CLR's eventing model is based on delegates.
* DELEGATE is a type-safe way to invoke a callback method.
* They are just function pointers, That is, they hold references to functions.
* A Delegate is a class. When you create an instance of it, you pass in the function name (as a parameter for the delegate's constructor) to which this delegate will refer.
* Delegates also intergrate the ability to call multiple methods serially and support the calling of static methods as well as instance methods.
*All delegate types are derived from MulticastDelegate which itself is derived from System.Delegate class which itself is derived from System.Object.
* The implementation of Equals compares two delegate objects to see whether their target is same or not.



class classdelg
{static int i=1;
public delegate void del(int a, string b);
public void delfunc(del d)
{
if (d != null)
d(i++, "success");
}
}
class funcdelg
{
public void outfunc(int a, string B)
{
Console.WriteLine("OUTFUNC {0},{1}",a,B);
}
}
class p1isas
{
static void infunc(int a, string b) //not a public function
{
Console.WriteLine("INFUNC {0},{1}", a, b);
}
static void Main()
{

classdelg cd = new classdelg();
funcdelg fd= new funcdelg();
classdelg.del d = null; //delegates are type property
d += new classdelg.del(infunc);
d += new classdelg.del(fd.outfunc);
cd.delfunc(d);
Console.Read();
}
}


Delegate Chains -

Feedback fb1 =new Feedback(Func1);
Feedback fb2= new Feedback(Func2);
Feedback fbchain= (Feedback) Delegate.Combine(fb1,fb2);
fb2 function will get invoke first.

EVENTS
* Event programming model that is popular in asynchronous programming.
* Delegate usefulness does not just lie in the fact that it can hold the references to functions but in the fact that it can define and use function names at runtime and not at compile time. A large goal of design delegates is their applicability in events model of .Net

Removing Delegates
Feedback fb1 =new Feedback(Func1);
Feedback fb2= new Feedback(Func2);
Feedback fbchain= (Feedback) Delegate.Combine(fb1,fb2);
Feedback fbchain= (Feedback) Delegate.Remove(fbchain, new Feedback(Func2) );

C# provides overloads of the += and -= for Delegate.Combine and Delegate.Remove