Wednesday, March 4, 2009

Accessing user name of a NTID using LDAP

public static string GetFirstName(string NTID)
{
char[] seperator ={','};
char[] sep1 = {'('};
string [] st = CheckLDAPUser(NTID).Split(seperator);
string[] sp = st[1].Split(sep1);
return sp[0].ToString();
}

private static string CheckLDAPUser(string ldapUserId)
{
System.DirectoryServices.DirectoryEntry directoryEntry = new System.DirectoryServices.DirectoryEntry("LDAP://CompanyNameURL");
System.DirectoryServices.DirectorySearcher directorySearcher = new System.DirectoryServices.DirectorySearcher(directoryEntry);
directorySearcher.Filter = "(SAMAccountName=" + ldapUserId + ")";
System.DirectoryServices.SearchResult sResultSet = directorySearcher.FindOne();
string fullName = "";
if (sResultSet != null)
{
if (sResultSet.Properties.Contains("displayName"))
{
fullName = sResultSet.Properties["displayName"][0].ToString();
}

return fullName;
}
return "Anonymous";
}

Wednesday, February 4, 2009

Readonly Listbox

Use the following snippet to extend the C# listBox to a readOnly List box.

using System.Windows.Forms;
namespace ReadOnlyListBox
{
public class ReadOnlyListBox : ListBox
{
private bool _readOnly = false;
public bool ReadOnly
{
get { return _readOnly; }
set { _readOnly = value; }
}

protected override void DefWndProc(ref Message m)
{
// If ReadOnly is set to true, then block any messages
// to the selection area from the mouse or keyboard.
// Let all other messages pass through to the
// Windows default implementation of DefWndProc.
if (!_readOnly || ((m.Msg <= 0x0200 || m.Msg >= 0x020E)
&& (m.Msg <= 0x0100 || m.Msg >= 0x0109)
&& m.Msg != 0x2111
&& m.Msg != 0x87))
{
base.DefWndProc(ref m);
}
}
}
}

Screen Right Bottom Co-Ordinates

Hi,

Use the following snippet to get the right bottom coordinates in the screen. This will be useful when you write apps which alerts the user from the system Tray.

Me.Left = Screen.PrimaryScreen.WorkingArea.Width - Me.Width
Me.Top = Screen.PrimaryScreen.WorkingArea.Height - Me.Height

Saturday, December 27, 2008

ASP.net Pitfall

Recently we faced a strange issue in one of the production servers. The session information was shared between 2 users in the ASP.net application. We then thought to print the Session ID in the browser and was perplexed to watch that 2 different sessions printing the same session id. I then googled out to see the possibility of
a session id getting duplicated but it was never possible. Then I got a vital information in the URL below

ASP.NET page is stored in the HTTP.sys

The culprit was output caching. When enabled the cache in the ASP.net kernel stores the page along with the set cookie response in the HTTP header. This causes the same page to be redirected to different users. A weird issue is'nt it. You can get the solution in the aforesaid URL.

Thursday, November 6, 2008

Browser Close Vs Session End in ASP.net

Browser Close Vs Session End in ASP.net

After a few R&D’s here goes my findings

There are n number of scenarios by which the browser can be closed viz

1. Clicking the (x) button
2. Clicking Alt+F4
3. File menu à Exit.
4. Alt+f+x

The OnUnload event will fire for all the above scenarios. So write a Javascript function like this which uses Remote scripting to Abandon the session in the Server side.

function abandonSession()
{
// Use remote scripting to
var xmlhttp;
if (window.ActiveXObject)
{ // IE
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET","AbandonSession.aspx",false);
xmlhttp.send();
}
}

Attach the above function in the HTML as shown below



In the page load of AbandonSession.aspx

protected void Page_Load(object sender, EventArgs e)
{
Session.Abandon();
// Write your code to logout the user since sometimes Session_End may not fire. Also Session_Event in Global.asax will not fire in Web farms.
}

However the weird thing is the OnUnload event also fires during following scenarios

1. When F5 or Page refresh is done
2. When the user types a different url in the same browser
3. Page is submitted or Post back happens
4. Click the browser back

So somehow you need to figure out a way which will not execute the abandonSession() function for all the above scenarios.

Sunday, October 12, 2008

Object.Equals C#

This is one of the basics which every .Net developer has to know. Hence I would like to explain this with a proper example.

Let us consider the following class.

class Employee
{
public Employee(int empID, string name)
{
this.empID = empID;
this.empName = name;
}

private int empID;

public int EmpID
{
get { return empID; }
set { empID = value; }
}
private string empName = string.Empty;

public string EmpName
{
get { return empName; }
set { empName = value; }
}
}

Now if I execute the folowing snippet of code

Employee emp1 = new Employee(1, "Ajeeth");
Employee emp2 = new Employee(1, "Ajeeth");
MessageBox.Show(emp1.Equals(emp2).ToString());
bool eq = (emp1 == emp2);
MessageBox.Show(eq.ToString());

The output would be

False
False

The reason being the Equals and == checks for the references by default. Hence it is necessary to override the Equals method in the Employee class which would now look like.

class Employee
{
public Employee(int empID, string name)
{
this.empID = empID;
this.empName = name;
}

private int empID;

public int EmpID
{
get { return empID; }
set { empID = value; }
}
private string empName = string.Empty;

public string EmpName
{
get { return empName; }
set { empName = value; }
}

public override bool Equals(object obj)
{
if (this.empID == (obj as Employee).empID)
return true;
return false;
}

public override int GetHashCode()
{
return this.empID;
}

public static bool operator ==(Employee emp1, Employee emp2)
{
return emp1.Equals(emp2);
}

public static bool operator !=(Employee emp1, Employee emp2)
{
return !(emp1 == emp2) ;
}

}

If you notice above I am overriding Equals and overloading the operator ‘==’ which internally calls the Employee.Equals() method. If you also see I am comparing the 2 objects of Employee object with their unique fields. This would enforce a value comparison. The C# compiler provides a warning if we forget to override the Object.GetHashCode() method when Object.Equals is overridden. The GetHashCode() should ensure that it returns unique id for 2 different objects of same class. This would impact the performance of HashTables if the objects are stored as Keys.

If you execute the following snippet would be

Employee emp1 = new Employee(1, "Ajeeth");
Employee emp2 = new Employee(1, "Ajeeth");
MessageBox.Show(emp1.Equals(emp2).ToString());
bool eq = (emp1 == emp2);
MessageBox.Show(eq.ToString());

The output would be

True
True

If you execute the following snippet would be

Employee emp1 = new Employee(1, "Ajeeth");
Employee emp2 = new Employee(2, "Aravind");
MessageBox.Show(emp1.Equals(emp2).ToString());
bool eq = (emp1 == emp2);
MessageBox.Show(eq.ToString());

The output would be

False
False

Happy Coding..

Thursday, October 9, 2008

Simple Authorization Framework

Note: I cant upload the source code here. If you need the source code please mail me at ajeeth4u@gmail.com

The authorization framework provides a generic mechanism to authorize each user’s request to complete an operation. It could be a Database Write, Read or Delete. From a more generic view there exist the following entities

1. Principal: – Any actor or role who initiates or request for an operation or Service.

2. Resource: – A resource is something which stores the business data. It could be a database table, XML file, Flat file etc.. The Principal can access the Resources through any Services and change the data using operations.

3. Service and Operation: A service could be a set of operations performed against a set of business entities which causes a change in their internal state.

4. Access Rights: Access rights are security mechanisms which can prevent or allow any Principal to call a Service or do any operations on a Resource.
All the above entities could vary from a business to business. Hence they have been generalized in the framework. The specialization of the entities could be done in the Framework extensions. For instance when it comes to the Data Repository project, the Principal could be an Organization’s Windows Principal Object. A Windows Principal represents the user who belongs to an AD group in the Organization domain.

The framework also has some extension points or hooks which can be extended by the client.

1. Rules Reader: The rules reader constructs the rules entity by reading from any persistent data storages like DB tables, XML files etc. The Authorization engine accepts a Rules object for the authorization strategy.
The framework has some frozen spots like the Rules Configuration, Authorization Strategy and the Authorization Context as an Authorization engine.

2. Rules Configurations: The access rights for each role have to be configured in a permanent storage. The storage could an XML file or could be a data base table. A rules configuration screen would be developed for the admin user to configure the rules. The sample screenshot for the screen is provided in the Appendix 8.2 of this document.

3. Rule Entity: The rule entity would be constructed by the Rules Reader and would be cached in entity.

4. Authorization Context: The authorization context should hold the 3 business entities Principal, Resource and Service/Operation. The authorization context would be sent to the authorization engine. The authorization engine parses the necessary information from the entities and implements a strategy to read the Access Rights for the context from the Rules Entity.

5. Authorization Strategy: The authorization strategy expects an Authorization context and a Rule entity to process the request and returns a Boolean flag true if the Principal is authorized to do the operation. The frozen strategy uses SQL server tables to configure the Rules, Principals and Access Rights. The schema details are provided further this document.



Sample Code

UI SaveButton_Clicked()
//Call the Business Layer
BLLookUpCodes objLookUpCodes = new BLLookUpCodes();
objLookUpCodes.Update(objTypedDataSet);

Business Layer

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Organization.DataAcess;


///
/// Summary description for BLLookupCodes
///

public class BLLookupCodes
{
public BLLookupCodes()
{
//
// TODO: Add constructor logic here
//
}

///
/// Calls the DAL to save the changes
///

/// dataset
public void Update(LookupCodeDataSet dataset)
{
//Create the authentication context
AuthenticationContext objContext = new AuthenticationContext();
//Set the Principal
objContext.Principal = HttpContext.Current.User.Identity.Name;
//Set the Table name
objContext.Resource = “InfLookupCodes”;
//Set the Operation name
objContext.Operation = “Update”;
//Build the Authorization Strategy
IAuthorizationStrategy objAuthStrategy= new OrganizationAuthorizationStategy();

//Authorize the user's role before calling the Data Access layer
if (objAuthStrategy.IsAuthorized(objContext))
{
//If Authorized call DAL
DALLooupCodes objDALLookupCodes = new DALLookUpCodes()
objDALLooupCodes.Update(dataset);
}
}
}

Configuration Schema details