Friday, September 11, 2009

Build a org structure based on loggedin user

I had a requirment to fetch the reporting manager and direct reports to the loggedin user. For this i have used a WSP builder. Then add the webpart feature at the project node level.
Added references to System.DirectoryServices and System.Security. The display of the hierarchy will be a tree structure. Following is the code snippet:

When the WebPart feature is added to the WSPBuilder project, the webpart cs file is also created. The two important functions are BuildStructure and CreateChildControls.

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.DirectoryServices;
using System.Security;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace WSPCreator
{
[Guid("25b6a3cf-4f71-43ca-bad0-dcb2c35b4152")]
public class UserStructureInOrganization : Microsoft.SharePoint.WebPartPages.WebPart
{
private bool _error = false;
private string _myProperty = null;


[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("My Property Group")]
[WebDisplayName("MyProperty")]
[WebDescription("Meaningless Property")]
public string MyProperty
{
get
{
if (_myProperty == null)
{
_myProperty = "Hello SharePoint";
}
return _myProperty;
}
set { _myProperty = value; }
}


public UserStructureInOrganization()
{
this.ExportMode = WebPartExportMode.All;
}

///
/// Create all your controls here for rendering.
/// Try to avoid using the RenderWebPart() method.
///

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

System.Security.Principal.IPrincipal User;
User = System.Web.HttpContext.Current.User;
string struser = User.Identity.Name;
string strusername = struser.Remove(0, struser.IndexOf("\\") + 1);

TreeView tvwOrg1 = new TreeView();
tvwOrg1.ID = "OrganizationStructure";
tvwOrg1.Width = Unit.Pixel(160);
tvwOrg1.Height = Unit.Pixel(250);
//strusername = "steeve";
BuildStructure(strusername, tvwOrg1);

this.Controls.Add(tvwOrg1);

}

private void BuildStructure(string strusr, TreeView tvwOrg)
{
DirectoryEntry DET = new DirectoryEntry("LDAP://ADServer");

DirectorySearcher DS = new DirectorySearcher(DET);
SearchResult RS;

DS.PropertiesToLoad.Add("manager");
DS.PropertiesToLoad.Add("directReports"); //People who report to steeve//

DS.Filter = ("(&(objectCategory=person)(objectClass=user)(samaccountname=" + strusr + "))");

//Only one manager for this object needs to be found//

RS = DS.FindOne();



DirectoryEntry Mgr = new DirectoryEntry("LDAP://" + RS.Properties["manager"][0].ToString());

//MessageBox.Show(Mgr.Properties["DisplayName"].Value.ToString());

string strUserMgr = Mgr.Properties["DisplayName"].Value.ToString() + " (Reporting Manager)";


TreeNode TN = new TreeNode(strUserMgr);

tvwOrg.Nodes.Add(TN);


TreeNode TNUser = new TreeNode(strusr);


TN.ChildNodes.Add(TNUser);


///end of part 1 gets the manager of the user//

//Gets directreportees for the user//
foreach (SearchResult RSUnderUser1 in DS.FindAll())
{
int icntchild1 = RSUnderUser1.Properties["directReports"].Count;

for (int IIchild1 = 0; IIchild1 < icntchild1; IIchild1++)
{

DirectoryEntry DE1 = new DirectoryEntry("LDAP://" + RSUnderUser1.Properties["directReports"][IIchild1].ToString());
if (DE1.Properties["DisplayName"].Value.ToString() != "")
{
TreeNode subTN = new TreeNode(DE1.Properties["DisplayName"].Value.ToString() + " (Team Member)");

TNUser.ChildNodes.Add(subTN);
}

}

}
/////////////////////////////////////////////////


//Start to get steeves sibblings// part - 3
DirectorySearcher DSMgr = new DirectorySearcher(Mgr);

//Add directreports//
DSMgr.PropertiesToLoad.Add("directReports");
DSMgr.PropertiesToLoad.Add("userPrincipalName");


DSMgr.Filter = ("(&(objectCategory=person)(objectClass=user)(samaccountname=" + strUserMgr + "))");

foreach (SearchResult RSUnderMgr in DSMgr.FindAll())
{
int icntchild = RSUnderMgr.Properties["directReports"].Count;

for (int IIchild = 0; IIchild < icntchild; IIchild++)
{

DirectoryEntry DE2 = new DirectoryEntry("LDAP://" + RSUnderMgr.Properties["directReports"][IIchild].ToString());

}

}

tvwOrg.ShowExpandCollapse = false;
tvwOrg.ExpandAll();

///////////////////////////////////////////////////////
}


///
/// Ensures that the CreateChildControls() is called before events.
/// Use CreateChildControls() to create your controls.
///

///
protected override void OnLoad(EventArgs e)
{
if (!_error)
{
try
{
base.OnLoad(e);
this.EnsureChildControls();

// Your code here...
}
catch (Exception ex)
{
HandleException(ex);
}
}
}

///
/// Clear all child controls and add an error message for display.
///

///
private void HandleException(Exception ex)
{
this._error = true;
this.Controls.Clear();
this.Controls.Add(new LiteralControl(ex.Message));
}
}
}

The advantage of using the WSPbuilder project is that it gives the WSP solution and also the bat files for deploying the WSP solution on the sharepoint server.

Tuesday, September 8, 2009

Why Should i use sharepoint, already have file server and network share for storing documents!!!

Often it is seen in existing development teams, there is a degree of lethargy to move or learn a newer technology especially if its from Microsoft. Making the agile teams adapt sharepoint is the most challenging task. They exactly know what they are doing, how they do it and why they do it when it comes to document storage. Questions arise, what has sharepoint to offer when it comes to document storage?
My take on this:
If your files are less than 50 MB in size
If you have a team where users are making changes to documents (same or different) and there is no control on tracking changes
How do you track a document that was changed several in last 10 minutes? i am sure you cant see the history of the documents using a file server or network share
check - in check out feature
Sharing document across without having to email thereby reducing network congestions or bottlenecks.
Sharepoint document library provides all the above features. Go for sharepoint implementation within your team.

Note: If your files size exceeds or is in the size of 300 MB, its best to go with file server or network share.

Thursday, June 25, 2009

Pulling Data from SQL Server Table into Sharepoint lists

In order to pull data from SQL Server table into a sharepoint list, there are 2 functionalities one must follow:

1. Use ADO.NET to connect to the SQL Server db
2. Use lists.asmx sharepoint web service.

I am providing sample code that one can use in their project and customize accordingly:

Create a Employee Table with the following fields
FirstName Varchar(50)
LastName Varchar(50)
Address Varchar(100)

Insert records in the SQL table Employee.

Create a Visual Studio 2005 VC# Console application called PullSQLTableToWSSList . Add web reference to http:\\yourservername\_vt_bin\lists.asmx. give the web reference name ListServ.

On the sharepoint site create a list called Employees User Title column as the FirstName, Create columns LastName and Address.

In the PullSQLTableToWSSList - program.cs file paste the following function. Pass the connection string:

private static void SharePointListFromDB(ListServ.Lists Asp, string strcon)
{

string sBatch = string.Empty;
string TotalBatch = string.Empty;
//Write code to form a XML document//
//Send that to update the batch file//
StreamWriter sw1 = new StreamWriter(sErrorLogPath + LogFileName, true);
try
{


sw1.WriteLine("Start with Records from DBI " + ":LogTime:" + DateTime.Now);


odbcon = new SqlConnection(strcon);
odbcon.Open();
//first cleanup the access database//
odcmd = new SqlCommand("Select * from Employee(nolock)", odbcon);
dr = odcmd.ExecuteReader();


//int chkcount = 0;
int intcount = 1;
while (dr.Read())
{

sw1.WriteLine("read started " + intcount + "record " + ":LogTime:" + DateTime.Now);
sBatch = "";
sBatch += "New";
sBatch += "" + dr["FirstName"].ToString() + "";
sBatch += "" + dr["LastName"].ToString() + "";
sBatch += "" + dr["Address"].ToString() + "";
sBatch += "
";

intcount++;
TotalBatch = TotalBatch + sBatch;

}

sw1.WriteLine(" Logtime" + DateTime.Now + "," + TotalBatch);

XmlDocument doc = new XmlDocument();
XmlElement batch_element = doc.CreateElement("Batch");
batch_element.InnerXml = TotalBatch;
XmlNode ndReturn = Asp.UpdateListItems("Employee", batch_element);
//Console.WriteLine(ndReturn.OuterXml.ToString());

sw1.WriteLine(ndReturn.OuterXml.ToString());
sw1.WriteLine(ndReturn.OuterXml.ToString() + " Logtime" + DateTime.Now);
sw1.Flush();
sw1.Close();
sw1.Dispose();

}
catch(Exception Ex)
{

sw1.WriteLine("SyncFromDBI: Error in Exception" + Ex.InnerException + " , " + Ex.Message + " Logtime" + DateTime.Now);
sw1.Flush();
sw1.Close();
sw1.Dispose();

}
odbcon.Close();
dr.Dispose();
odcmd.Dispose();
odbcon.Dispose();

}

Do not forget to provide reference to System.IO and System.Data.SQLClient.

Run the console application. Open the sharepoitn list. ola!!! you see the records form the tables pulled into the sharepoint list.

Wednesday, December 17, 2008

Traversing through files in a folder using foreach file enumerator - SSIS


Figure 1.0
Following are the steps to read all the files in a folder using the foreach file enumerator.
1. Open dtsx package in the BIDS project.
2. In the Control flow, drag and drop foreach container.
3. dblclick on the foreach container,
In the collection choose the foreach file enumerator,
set the Enumerator configuration, Folder and files to choose from.
4. In the variable mapping, create a new variable
5.Click ok.
6. Add Data Flow task in the Foreach container.
7.In the DataFlow, drag a Flat File connection.
double click on the Flat file source, create new (Figure 1.0)
select the filename from the path and accordingly set the columns.
8. Then add the OLEDB data destination and make setting to point to the destination table.
9. Run the package.




Saturday, December 13, 2008

Using dropdownlist value in filterexpression of GridView.

Why AJAX?
Simply put it as if the user does not want to see a flicker on the screen on every postback and needs a winform like experience then making AJAX enabled website is the solution.
What is required to make a AJAX enabled web site?
Every ASPX page will have one and only one instance of script manager control. UpdatePanel control can be added as many are needed. Each server side control should be placed inside the contenttemplate tag of the UpdatePanel control. Thats all it is to make a AJAX enabled web site.
Sample Project:
Requirement: In SQL Server 2005, there is a users table.Using a ASPX web page this table new data needs to be inserted and updated.This page should be AJAX enabled.
Approach:
1.Quickly create a AJAX enabled web site in VS 2005.
2.Add a MasterPage in the project.
3.Add content page for the MasterPage.
4.Create stylesheet and add the stylesheet reference in the head tag of the

MasterPage.
What is a MasterPage?
A MasterPage is a central location where all the common functionality\features can be addressed and all the content pages will inherit from this Masterpage. This will ensure consistent looknfeel across the webapplication.

5.Create a objectdatasource for the gridview control. Add the FilterExpression property and set the value as "USERNAME Like '{0}%'" and add the . thats it.

Thursday, December 11, 2008

In asp.net 1.1 the connectionstring can be extracted using the ConfigurationSettings.AppSettings("KeyName").

In asp.net 2.0 there is a connectionstring section provided in the web.config file. The way to extract this string is to use
Configuration.ConfigurationManager.ConnectionStrings["connstr"].ConnectionString.

One more thing asp.net 2.0 host the web app under development in the asp.net development server and dynamic ports can be assigned. This is different then the way webapps were developed in the asp.net 1.1 which required IIS to be installed on the development machines.

Wednesday, December 10, 2008

Problem with vista user connecting to SQL Server 2005

After i had installed SQL Server 2005 on the default instance on vista home edition under local system account. When i tried to connect to the SQL Server database in vista, the login failed. I had spent good 5 hours to dig the problem. I had then downloaded SQL Server 2005 sp2 and installed it. Again when i tried to connect, the connection failed. There is a utility in the location C:\Program Files\Microsoft SQL Server\90\Shared\sqlprov.exe, which needs to be run to provide sysadmin privileges to the vista local user. Before doing this i turned on the UAC for the vista user in the control panel. After giving the vista user sysadmin privileges, i was able to connect to the SQL Server 2005 default instance.