Friday, April 15, 2011

Access Active Directory in .NET

During one of my client requirements, I played a lot with active directory to display user data in a web application from active directory.

Here goes a generic class with some functions to get get user information from active directory:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.DirectoryServices;
using System.Collections;

namespace Common
{
public class ActiveDirectory
{
string domainPath = "GC://YourGC/DC=YourDomain,dc=YourOU,dc=com";

//Get Single user info
public DataTable GetUserInfo(string sLogonName)
{
/*Getting user data from active directory*/
DirectoryEntry entry = new DirectoryEntry(domainPath);
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = "(&(objectClass=user)(sAMAccountName=" + sLogonName + "))";
SearchResult result = searcher.FindOne();

/*Creating a datatable to store user data*/
DataTable resultTable = new DataTable("UserData");
resultTable.Columns.Add("givenname");
resultTable.Columns.Add("sn");
resultTable.Columns.Add("title");
resultTable.Columns.Add("telephoneNumber");
resultTable.Columns.Add("company");
resultTable.Columns.Add("mail");
resultTable.Columns.Add("department");
resultTable.Columns.Add("manager");

DataRow resultRow = resultTable.NewRow();

if (result.Properties.Count > 0)
{
try
{
resultRow["givenname"] = result.Properties["givenname"][0].ToString();
}
catch (Exception)
{
resultRow["givenname"] = string.Empty;
}
try
{
resultRow["sn"] = result.Properties["sn"][0].ToString();
}
catch (Exception)
{
resultRow["sn"] = string.Empty;
}
try
{
resultRow["title"] = result.Properties["title"][0].ToString();
}
catch (Exception)
{
resultRow["title"] = string.Empty;
}
try
{
resultRow["telephoneNumber"] = result.Properties["telephoneNumber"][0].ToString();
}
catch (Exception)
{
resultRow["telephoneNumber"] = string.Empty;
}
try
{
resultRow["company"] = result.Properties["company"][0].ToString();
}
catch (Exception)
{
resultRow["company"] = string.Empty;
}
try
{
resultRow["mail"] = result.Properties["mail"][0].ToString();
}
catch (Exception)
{
resultRow["mail"] = string.Empty;
}
try
{
resultRow["department"] = result.Properties["department"][0].ToString();
}
catch (Exception)
{
resultRow["department"] = string.Empty;
}
try
{
resultRow["manager"] = result.Properties["manager"][0].ToString();
}
catch (Exception)
{
resultRow["manager"] = string.Empty;
}
resultTable.Rows.Add(resultRow);
}
else
{

}
return resultTable;
}

//Get all domain users multiple properties in data table
public DataTable GetAllUserInfo()
{
/*Getting user data from active directory*/
DirectoryEntry entry = new DirectoryEntry(domainPath);
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.PageSize = 1000;

searcher.Filter = "(&(objectClass=user)(objectCategory=person))"; //to get users only
SearchResultCollection resultCollection = searcher.FindAll();

/*Creating a datatable to store user data*/
DataTable resultTable = new DataTable("UserData");
resultTable.Columns.Add("givenname");
resultTable.Columns.Add("sn");
resultTable.Columns.Add("title");
resultTable.Columns.Add("telephoneNumber");
resultTable.Columns.Add("company");
resultTable.Columns.Add("mail");
resultTable.Columns.Add("department");

SearchResult result;
if (resultCollection != null)
{
for (int counter = 0; counter < resultCollection.Count; counter++)
{
DataRow resultRow = resultTable.NewRow();

result = resultCollection[counter];
if (result.Properties.Contains("givenname"))
{
resultRow["givenname"] = result.Properties["givenname"][0].ToString();
}
if (result.Properties.Contains("sn"))
{
resultRow["sn"] = result.Properties["sn"][0].ToString();
}
if (result.Properties.Contains("title"))
{
resultRow["title"] = result.Properties["title"][0].ToString();
}
if (result.Properties.Contains("telephoneNumber"))
{
resultRow["telephoneNumber"] = result.Properties["telephoneNumber"][0].ToString();
}
if (result.Properties.Contains("company"))
{
resultRow["company"] = result.Properties["company"][0].ToString();
}
if (result.Properties.Contains("mail"))
{
resultRow["mail"] = result.Properties["mail"][0].ToString();
}
if (result.Properties.Contains("department"))
{
resultRow["department"] = result.Properties["department"][0].ToString();
}
resultTable.Rows.Add(resultRow);
}
}
return resultTable;
}


//Get all domain users single property in array list
public ArrayList GetAllADDomainUsers()
{
ArrayList allUsers = new ArrayList();

DirectoryEntry searchRoot = new DirectoryEntry(domainPath);
DirectorySearcher search = new DirectorySearcher(searchRoot);
search.Filter = "(&(objectClass=user)(objectCategory=person))";

SearchResult result;
SearchResultCollection resultCol = search.FindAll();
if (resultCol != null)
{
for (int counter = 0; counter < resultCol.Count; counter++)
{
result = resultCol[counter];
if (result.Properties.Contains("samaccountname"))
{
allUsers.Add((String)result.Properties["samaccountname"][0]);
}
}
}
return allUsers;
}
}
}



Happy Coding!!!

Wednesday, April 13, 2011

Error & information logging; event viewer or text file

We can log different errors or information while writing code for any .NET application, here is a generic class written for logging:

Code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Security.Permissions;

namespace Common
{
/*This Class is used for logging messages to either a custom EventViewer or in a plain text file located on web server.
* Owner : Deepak Solanki
* Year : 2011 */

public class Logging
{
#region "Variables"

private string sLogFormat;
private string sErrorTime;

#endregion


#region "Local methods"

/* Write to Txt Log File*/
public void WriteToLogFile(string sErrMsg)
{
try
{
//sLogFormat used to create log format :
// dd/mm/yyyy hh:mm:ss AM/PM ==> Log Message
sLogFormat = DateTime.Now.ToShortDateString().ToString() + " " + DateTime.Now.ToLongTimeString().ToString() + " ==> ";

//this variable used to create log filename format "
//for example filename : ErrorLogYYYYMMDD
string sYear = DateTime.Now.Year.ToString();
string sMonth = DateTime.Now.Month.ToString();
string sDay = DateTime.Now.Day.ToString();
sErrorTime = sYear + sMonth + sDay;

//writing to log file
string sPathName = "C:\\Logs\\ErrorLog" + sErrorTime;
StreamWriter sw = new StreamWriter(sPathName + ".txt", true);
sw.WriteLine(sLogFormat + sErrMsg);
sw.Flush();
sw.Close();
}
catch (Exception ex)
{
WriteToEventLog("MySite", "Logging.WriteToLogFile", "Error: " + ex.ToString(), EventLogEntryType.Error);
}
}

/* Write to Event Log*/
public void WriteToEventLog(string sLog, string sSource, string message, EventLogEntryType level)
{
//RegistryPermission regPermission = new RegistryPermission(PermissionState.Unrestricted);
//regPermission.Assert();

if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);

EventLog.WriteEntry(sSource, message, level);
}

#endregion
}
}


Happy Coding!!!

Web part to show data from list

Requirement is to show news on web page, data saved in custom list . A webpart to get data from list and show on page:

1. Open Visual Studio and create a class file or webpart (if sharepoint extension is there with VS.
2. Code of ShowNews.cs file below:


using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.Drawing;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace MyWebParts
{
[Guid("6e1a7cf2-bf98-4926-81c9-0c0184ba6a60")]
public class ShowNews : System.Web.UI.WebControls.WebParts.WebPart
{

//Controls
private Label lblTitle;
private Label lblNews;

// A table that is used to layout the controls
private Table tbMain;
private TableRow tRow;
private TableCell tCell;

#region "Web Part Properties"

private const string defaultSiteCollection = "NewTeamSite";
private string _siteName = defaultSiteCollection;
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true),
WebDisplayName("Site Name"),
WebDescription("Site from where to fetch News")]

public string SiteName
{
get { return this._siteName; }
set { this._siteName = value; }
}

private const string defaultList = "News";
private string _listName = defaultList;
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true),
WebDisplayName("List Name"),
WebDescription("List from where to fetch News")]

public string ListName
{
get { return this._listName; }
set { this._listName = value; }
}
#endregion

public ShowNews()
{
}

protected override void CreateChildControls()
{
base.CreateChildControls();

// TODO: add custom rendering code here.
tbMain = new Table();
tbMain.BorderStyle = BorderStyle.Double;
tbMain.BorderColor = Color.Silver;
tbMain.BackColor = Color.WhiteSmoke;


lblTitle = new Label();
lblTitle.Text = "News";
lblTitle.Font.Bold = true;

tRow = new TableRow();
tCell = new TableCell();
tCell.VerticalAlign = VerticalAlign.Top;
tCell.HorizontalAlign = HorizontalAlign.Center;
tCell.Controls.Add(lblTitle);
tRow.Controls.Add(tCell);
tbMain.Controls.Add(tRow);


lblNews = new Label();
lblNews.Text = "Blank";

tRow = new TableRow();
tCell = new TableCell();
tCell.VerticalAlign = VerticalAlign.Top;
tCell.HorizontalAlign = HorizontalAlign.Left;
tCell.Controls.Add(lblNews);
tRow.Controls.Add(tCell);
tbMain.Controls.Add(tRow);

this.Controls.Add(tbMain);

CreateNewsHtml();
}

private void CreateNewsHtml()
{
SPList newsList;
SPListItemCollection listitemcoll;

try
{
using (SPSite site = new SPSite(this.Context.Request.Url.ToString()))
{
using (SPWeb web = site.AllWebs[this._siteName])
{
newsList =web.Lists[this._listName];
listitemcoll = newsList.Items;
if (newsList.ItemCount > 0)
foreach(SPListItem item in listitemcoll)
{
lblTitle.Text = item["Title"].ToString();
lblNews.Text = item["News"].ToString();
}

}
}
}
catch (Exception ex)
{

}
}
}
}


3. Create ShowNews.webpart file (get created itself with Sharepoint extension)

<?xml version="1.0" encoding="utf-8"?>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="MyWebparts.ShowNews, ShowNews, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXXX" />
<importErrorMessage>Cannot import ShowNews Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name="Title" type="string">ShowNews Web Part</property>
<property name="Description" type="string">Show News from List on Page</property>
<property name="AllowZoneChange" type="bool">True</property>
<property name="AllowHide" type="bool">True</property>
</properties>
</data>
</webPart>
</webParts>


4. Now, your webpart is ready, deploy it either [1] manually; GAC the DLL, upload webpart file to webpart gallery and made safecontrol entry for webpart in web.config file. or [2] create a deployment package to deploy the webpart.

Happy Coding!!!

Friday, April 8, 2011

User Control for Tab Navigation

While developing a portal we came across a requirement where a tab navigation to be created and added in master page of the site. Here are the simple steps of how to create a tab navigation using ASP MENU control.

1. Go to your site/project and add a user control as new item.
2. There will be added one .ASCX file and one code file .ASCX.CS
3. We are not using code file here so delete code file (.ascx.cs)
4. Also delete code file reference from <%@ Control ... directive line (first line in file).

write the code to add asp menu and SiteMapDataSource
code below:

<%@ Control Language="C#" AutoEventWireup="true" %>
<div id="TabDiv" runat="server">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="TabMenuContainer">
<tr>
<td>
<asp:Menu CssClass="TabMenu" DataSourceID="CampaignPortalSiteMap" HideSelectElements="True"
ID="Menu2" Orientation="Horizontal" runat="server">
<StaticSelectedStyle CssClass="TabMenuItemSelected" />
<StaticMenuItemStyle CssClass="TabMenuItem" />
<StaticMenuStyle CssClass="SiteStaticMenu" />
<StaticHoverStyle CssClass="TabMenuItemHover" />
<DataBindings>
<asp:MenuItemBinding DataMember="SiteMapNode" Depth="0" NavigateUrlField="Url" TextField="Title"
ToolTipField="Description" />
</DataBindings>
</asp:Menu>
</td>
<td class="TabMenuSpacer" width="100%">
</td>
</tr>
</table>
</div>
<asp:SiteMapDataSource ID="CampaignPortalSiteMap" runat="server" ShowStartingNode="false"
SiteMapProvider="PortalSiteMap" />


In the code above:
ASP Menu control create navigation, it takes either a sitemap source as data source that can be bind to it, or menu items (statically or through code).

SiteMapDataSource is the sitemap provider reference, sitemap provider will be specified in web.config file of application.

There are many CSS classes for styling of tabs, that will be there in application's CSS file.

5. Now add the CSS file to define style classes, style sheet below:

body
{
font-family: Tahoma;
}

#MasterContainer
{
border: solid 1px black;
}

#BannerContainer
{
padding: 5px 5px 5px 5px;
font-weight: bold;
font-size: large;
}

.TabMenuContainer
{
border-top: solid 1px black;
}

.TabMenuItem
{
background-color: #FFFFBC;
text-align:center;
font-size: xx-small;
border: solid 1px black;
border-left: none;
padding: 3px 3px 3px 3px;
}
.TabMenuItemSelected
{
background-color: White;
text-align:center;
font-size: xx-small;
border-right: solid 1px black;
border-bottom: none;
border-top: none;
border-left: none;
padding: 5px 3px 5px 3px;
}
.TabMenuItemHover
{
color:Black;
font-weight: bold;
}
.SiteStaticMenu
{
margin: -1px 0px 0px 0px;
background-color: Black;
}
.TabMenuSpacer
{
background-color: #222222;
padding: 5px 5px 5px 5px;
}

#SiteContent
{
padding: 5px 5px 5px 5px;
margin: 10px 10px 10px 10px;
width: 100%;
}

.SiteContentSpacer
{
height: 200px;
visibility: hidden;
}#FooterContainer
{
font-size: xx-small;
border-top: solid 1px black;
}

Till now we are done with menu control and its look and feel, now we need to define the data source for that menu control.

6. Open web.config file of web application, go to section and add a provider that we had specified in used control.

<providers>
<add name="PortalSiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="portal.sitemap" />
</providers>

The last thing left now is to define sitemap file "portal.sitemap" from where asp menu would pick it's menu items.

7. Add a new sitemap item in project, naming portal.sitemap and put links, titles... of pages in specified xml format, sitemap xml below:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/ AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="" description="" roles="*">
<siteMapNode url="~/Home.aspx" title="Home" description="The home page" roles="*" />
<siteMapNode url="~/default2.aspx" title="Tab 1" description="The first tab" roles="*" />
<siteMapNode url="~/default.aspx" title="Google" description="Google search" roles="*" />
<siteMapNode url="http://www.yahoo.com" title="Yahoo" description="Yahoo search" roles="*" />
</siteMapNode>
</siteMap>


All set now, put this user control on your master page or page, wherever required and navigate...Cheers :-)

Happy Coding!!!