基于AD的用户组织目录树选择工具的解决方案
2009-03-06 11:00 by Virus-BeautyCode, 1675 阅读, 5 评论, 收藏, 编辑
本文的需求来自进来SharePoint开发中的人员选择,基础中国的用户更加喜欢通过组织结构来选择人员,这样可以清晰的知道选择人员的部门,通过组织结构选择人员是本文的讨论点。
我也是集合了前人的思路,进行了整合,参考了下面的博客
基于AD的用户组织目录树选择工具的解决方案
http://blog.lickies.cn/Lists/Posts/Post.aspx?List=34201ce7%2Dcc0e%2D452a%2D949a%2Dffcf74a1780a&ID=31
asp.net(C#)弹出窗口返回值并刷新主窗体
http://blog.csdn.net/taoyinzhou/archive/2007/12/12/1930668.aspx
使用C#中的DirectorySearcher来获得活动目录中的组织结构与用户等信息,并在展示成树形结构(附源代码)
http://www.cnblogs.com/KingOfSoft/archive/2007/05/12/743693.html
感谢三位作者的无私奉献,为我的这篇博客提供了资料。
我的整个实现是由三个页面组成,首先是一个信息填写页面WebForm1.aspx,有一栏为选择任务的执行人员
WebForm1.aspx页面代码如下
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
<style type="text/css">
body
{ font-size:12px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<table style="width: 100%;">
<tr>
<td style="width:100px;">
任务标题:</td>
<td>
<asp:TextBox ID="TextBox2" runat="server" Width="500px"></asp:TextBox>
</td>
</tr>
<tr>
<td style="width:100px;">
任务内容:</td>
<td>
<asp:TextBox ID="TextBox3" runat="server" Height="117px" TextMode="MultiLine"
Width="500px"></asp:TextBox>
</td>
</tr>
<tr>
<td style="width:100px;">
代办人:</td>
<td>
<asp:TextBox ID="TextBox1" runat="server" Width="500px">这是初始值,将被传递到新窗口。</asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="打开窗口" Width="96px"
onclick="Button1_Click" />
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
WebForm1.aspx的后台代码如下
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace WebApp
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!ClientScript. IsClientScriptBlockRegistered("clientScript"))
{
System.Text.StringBuilder sbScript = new System.Text.StringBuilder();
sbScript.Append("<script>");
sbScript.Append("function OpenWin(){");
sbScript.Append(Environment.NewLine);
sbScript.Append("var str=window.showModalDialog(‘WebForm2.aspx‘,document.form1.TextBox1.value,‘dialogWidth=800px;dialogHeight=700px‘,‘scroll:yes‘);");
sbScript.Append(@"if(str!=null)
{
var users=str;
document.form1.TextBox1.value=users.substring(0,users.lastIndexOf(‘,‘));
}
");
sbScript.Append("}");
sbScript.Append("</script>");
ClientScript. RegisterClientScriptBlock(this.GetType(),"clientScript", sbScript.ToString());
}
Button1.Attributes.Add("onclick", "OpenWin()");
}
protected void Button1_Click(object sender, EventArgs e)
{
}
}
}
弹出窗口如下图,是用一个页面,里面嵌套一个iframe,防止回发之后页面消失WebForm2.aspx嵌套ADOperTest.aspx
WebForm2.aspx页面文件,没有后台代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApp.WebForm2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title> <style type="text/css">
body
{ font-size:12px;
}
</style>
</head>
<body>
<iframe src="ADOperTest.aspx" id="iframe1" width="1600px" height="1400px"></iframe>
</body>
</html>
后台代码
ADOperTest.aspx 页面代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ADOperTest.aspx.cs" Inherits="WebApp.ADOperTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<style type="text/css">
body
{ font-size:12px;
}
</style>
<title>无标题页</title>
</head>
<body id="MyBody" runat="server" ms_positioning="GridLayout">
<form id="Form1" runat="server" method="post">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<input id="Hidden1" type="hidden" runat=server />
</div>
<table>
<tr>
<td>
<fieldset>
<legend>组织单元</legend>
<div style="overflow: auto; height: 200px; width: 100px;">
<asp:TreeView ID="TreeView1" runat="server"
onselectednodechanged="TreeView1_SelectedNodeChanged">
</asp:TreeView></div>
</fieldset>
</td>
<td>
<fieldset>
<legend>人员</legend>
<div style="overflow: auto; height: 200px; width: 100px;">
<asp:DataList ID="DataList1" runat="server">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Text= ‘<%# Eval("UserName") %>‘ />
</ItemTemplate>
</asp:DataList>
</div>
</fieldset>
</td>
<td>
<fieldset>
<legend>操作</legend>
<div style="overflow: auto; height: 200px; width: 52px;" >
<asp:Button ID="btnAdd" runat="server" Text=">>" Width=50px onclick="btnAdd_Click" />
<br />
<br />
<asp:Button ID="btnDel"
runat="server" Text="<<" Width=50px onclick="btnDel_Click"/>
</div>
</fieldset>
</td>
<td>
<fieldset>
<legend>选中的人员</legend>
<div style="overflow: auto; height: 200px; width:100px;">
<asp:DataList ID="DataList2" runat="server">
<ItemTemplate>
<asp:CheckBox ID="CheckBox2" runat="server" Text= ‘<%# Eval("UserName") %>‘ />
</ItemTemplate>
</asp:DataList>
</div>
</fieldset>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="确定" onclick="Button1_Click" />
</form>
</body>
</html>
ADOperTest.aspx.cs后台代码
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
namespace WebApp
{
public partial class ADOperTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string vbCrLf = " ";
if (!IsPostBack)
{
DirectoryEntry entry = new DirectoryEntry("LDAP://192.168.203.222", "administrator", "demo");
DirectoryEntry ou = entry.Children.Find("OU=virus", "organizationalUnit");
TreeNode ouTree = new TreeNode();
getOUTree(ouTree, ou);
TreeView1.Nodes.Add(ouTree);
DataList1.DataSource = null;
DataList1.DataBind();
DataList2.DataSource = null;
DataList2.DataBind();
Session["SelectedUsers"] = null;
}
string strScript = "<script>" + vbCrLf;
strScript += @"function closewin(){
var valuehiden=document.getElementById(‘Hidden1‘).value;
window.parent.returnValue=valuehiden;" + vbCrLf;
strScript += "window.parent.close();}" + vbCrLf;
strScript += "</script>" + vbCrLf;
if (!ClientScript.IsClientScriptBlockRegistered("clientScript"))
ClientScript.RegisterClientScriptBlock(this.GetType(), "clientScript", strScript);
Button1.Attributes.Add("onclick", "closewin()");
MyBody.Attributes.Add("onload", "document.Form1.TextBox1.value=window.parent.dialogArguments");
}
/// <summary>
/// 加载公司组织结构
/// </summary>
/// <param name="ouTree"></param>
/// <param name="entry"></param>
private void getOUTree(TreeNode ouTree, DirectoryEntry entry)
{
foreach (DirectoryEntry de in entry.Children)
{
if (!de.SchemaClassName.ToLower().Equals("user"))
{
TreeNode ouChildNode = new TreeNode();
//ouChildNode.Text = de.Name+"|"+de.SchemaClassName;
ouChildNode.Text = de.Name.Substring(de.Name.IndexOf("=") + 1);
ouChildNode.Value = de.Name;
ouTree.ChildNodes.Add(ouChildNode);
if (de.Children != null)
{
getOUTree(ouChildNode, de);
}
}
}
}
/// <summary>
/// 加载选中组织结构中的人员信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
TextBox1.Text = ((TreeView)sender).SelectedNode.Text;
TreeNode node = ((TreeView)sender).SelectedNode;
DataTable dt = new DataTable();
dt.Columns.Add("UserName");
DataRow dr;
DirectoryEntry entry = new DirectoryEntry("LDAP://192.168.203.222", "administrator", "demo");
DirectorySearcher searcher = new DirectorySearcher();
searcher.Filter = "objectClass=user";
DirectoryEntry ou = entry.Children.Find("OU=virus", "organizationalUnit");
searcher.SearchRoot = ou;
SearchResultCollection users = searcher.FindAll();
foreach (SearchResult sr in users)
{
if (sr.Path.Split(‘,‘)[1].ToLower().Equals(node.Value.ToLower()))
{
dr = dt.NewRow();
//dr["UserName"] = sr.Path;
dr["UserName"] = sr.Properties["name"][0];
dt.Rows.Add(dr);
}
}
DataList1.DataSource = dt;
DataList1.DataBind();
}
/// <summary>
/// 调整人员:添加人员
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnAdd_Click(object sender, EventArgs e)
{
DataTable dt;
if (Session["SelectedUsers"] == null)
{
dt = new DataTable();
dt.Columns.Add("UserName");
}
else
{
dt = (DataTable)Session["SelectedUsers"];
}
DataRow dr;
bool isAdded = false;
//Hidden1.Value = "";
foreach (DataListItem item in DataList1.Items)
{
isAdded = ((CheckBox)item.FindControl("CheckBox1")).Checked;
if (isAdded)
{
//Hidden1.Value += ((CheckBox)item.FindControl("CheckBox1")).Text+",";
dr = dt.NewRow();
dr["UserName"] = ((CheckBox)item.FindControl("CheckBox1")).Text;
if (dt.Select("UserName=‘" + dr["UserName"].ToString() + "‘").Length == 0)
dt.Rows.Add(dr);
else
continue;
}
}
Session["SelectedUsers"] = dt;
DataList2.DataSource = dt;
DataList2.DataBind();
getSelectedUsers();
}
private void getSelectedUsers()
{
bool isAdded = false;
Hidden1.Value = "";
foreach (DataListItem item in DataList2.Items)
{
Hidden1.Value += ((CheckBox)item.FindControl("CheckBox2")).Text + ",";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
}
/// <summary>
/// 调整人员:删除选中人员
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnDel_Click(object sender, EventArgs e)
{
bool isDeled = false;
DataTable dt = (DataTable)Session["SelectedUsers"];
foreach (DataListItem i in DataList2.Items)
{
isDeled = ((CheckBox)i.FindControl("CheckBox2")).Checked;
if (isDeled)
{
dt.Rows[i.ItemIndex].Delete();
}
}
DataList2.DataSource = dt;
DataList2.DataBind(); getSelectedUsers();
}
}
}
这个东西本来是SharePoint开发过程中出来的需求,可是返回的只是一个组合了用户姓名的字符串,不能变成SPUser对象,SPUser对象又没有构造函数,有没有研究过这个呢,如果有的话,可以给我留言,谢谢了。