下面的文章我想以一个具体的BUG跟踪Demo来说明MOSS的具体应用,这里面会应用到下面的知识点:
1:用户组,用户的创建,权限分配;
2:列表的概念以及创建;
3:利用用户控件来完成表单的增加加功能;
4:当前域用户查看自己BUG。
BUG跟踪软件在一些大型公司一般都有,上次在客户公司做项目时,他们用一个叫做QC的软件,以WEB形式展现,有大概以下几点功能:
1:域用户可以提交BUG给指定的人员去解决;
2:程序员可以根据条件查询自己的BUG数据并返回处理结果;
3:管理员可以通过BUG报表清晰的看出整个项目的BUG解决程序。
非常好用。下面我就根据这一原理做一个简单的Demo,简化版的,只是实现思路而已。既然要用到列表,这里就像说下WSS VS MO,目前WSS v3 共有35个命名空间,经常使用的核心名称空间如下:
1:Microsoft.SharePoint;
2:Microsoft.SharePoint.WebControls;
3:Microsoft.SharePoint.Utilities;
4:Microsoft.SharePoint.Administration;
5:Microsoft.SharePoint.Navigation;
6:Microsoft.SharePoint.WebPartPages;
7:Microsoft.SharePoint.Workflow;
8Microsoft.SharePointSearch.Query。
WSS V3的几个核心类关系图如下:SPSite是核心类之一,它是SPWeb 对象集合,代表站点集。SPWeb 则代表一个具体的站点,它包含SPList集合。SPList代表列表或者是文档库,它是SPListItem 的对象集合。SPListItem类代表列表中的行,或者是文档库中的独立文档,通过它可以访问到具体的行数据或者是文档内的数据。
第一:测试员要想报一个bug给开发员解决,那么首先要创建用户组和成员。
1:确保公司有一个统一的域环境,(没有域环境谈何MOSS);
2:增加用户到域;
3:在MOSS站点中添加组。操作步骤:网站操作-网站设置-人员和组-新建-新建用户组。
1):首先要创建一个manager的组,用来充当管理员,同时给manager组加上相应的权限,可以根据实际情况,我这里加的是完全控制。
2):再加一个开发人员的组developer,在加权限时,加上参与讨论和读取,相当于可写可读;
3):再加一个测试组tester,权限和developer一样就行。
4:将用户划分到相应的组。在上面的三个组中,分别加入相应的用户。
第二:列表的创建。MOSS中的列表是整个MOSS的数据基础,其实相当于数据库中的一个表。对应我们的BUG系统,很明显需要一个记录BUG详情的列表,这里我创建了一个名为bug2的列表,为了以后的数据查询方便,在这里创建列表栏名时需要注意一个问题:首次创建栏名时,系统会根据栏名生成系统中对应的表字段名(internal name),但它有一个要求,这个栏名最好是字母,且中间不要产生空格,因为在生成internal name时,会将空格以及中文编码,这样会导致开发员做列表查询时不清楚表字段的名称。下面的栏名都是不太好的做法:解决人员,解决 人员,jack chen,纯英文字段对于中文系统来说还是不完美的,我们可以第二次修改栏名为中文,这样在显示上就友好些,且internal name不会因此发生变化。为了简单我这里创建了以下字段:
1:BUG标题:sTitel;
2:BUG描述:sDesc ;
3:重要性:importance,一个下拉框,重要,一般,低三种。
4:解决人员:sUser,存储域用户名称,友好的(例如:姜敏),不是登录名。
5:项目:project,一般在开发时,一个开发员会同时接手几个项目。
6:状态:status,默认值为未解决。如果开发员解决后可以更改成已解决状态。
第三:用户控件的创建。由于web part项目开发起来比起用户控件麻烦一点,这里我采用用户控件的形式来实现。创建一个web application工程,然后创建一个QCWeb.ascx控件,用来让测试人员填写BUG并指给相应的开发员解决。最终的页面展示如下图。
1:绑定解决人员数据,代码如下。
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 绑定开发人员名单
/// </summary>
private void getDeveloper()
{
DataTable dr = new DataTable();
dr.Columns.Add("sName", typeof(string));
SPWeb rootWeb = SPControl.GetContextSite(Context).RootWeb;
foreach (SPUser user in rootWeb.Groups["developer"].Users)
{
if (user.Name != "系统帐户")
{
DataRow dt =dr.NewRow ();
dt[0] = user.Name;
dr.Rows.Add(dt);
}
}
this.ddlDeveloper.DataSource = dr;
this.ddlDeveloper.DataTextField = "sName";
this.ddlDeveloper.DataValueField = "sName";
this.ddlDeveloper.DataBind();
}
代码说明:根据rootWeb.Groups["developer"].Users获取开发人员所有组员的人员集合,除掉系统帐户,把所有的用户信息附加到下拉列表框中。下面是关于操作用户和用户组的对象模型说明:
1):SPUser:用户对象,域用户;
2):SPUserCollection:用户对象集合;例如:rootWeb.Groups["developer"].Users
3):SPGroup:用户组;
4):SPGroupCollection:用户组的集合。
2:提交BUG的事件程序如下:我在开发时遇到一个问题就是如何取域用户的友好名称?例如当前的域:a.com,用户名:jiangmin,域用户信息中的友好名称为姜敏。我总结以了以个几种关于取域用户信息的方法:
1):User.Identity.Name; //读取域登录用户名,格式为Domainname\\username (域名名称"用户名称),返回结果a.com\\jiangmin;
2):username返回结果jiangmin ;
3):SPContext.Current.Web.CurrentUser.Name,返回结果:姜敏,如果当前用户是系统帐户的话会显示成系统帐户,这显示是我们希望看到的结果。
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
try
{
SPWeb web = SPControl.GetContextSite(Context).RootWeb;
SPList list = web.Lists[sourceList];
SPListItemCollection lists = list.Items;
SPListItem listItem = list.Items.Add();
listItem["sTitle"] = this.txtTitle.Text.Trim();
listItem["sDesc"] = this.txtDesc.Text;
listItem["importance"] = this.ddlimportance.SelectedValue;
SPUser developer=null ;
foreach (SPUser user in web.Groups["developer"].Users)
{
if (user.Name == this.ddlDeveloper.SelectedValue)
{
developer = user;
break;
}
}
listItem["sUser"] = developer;
listItem["project"] = this.ddlProject.SelectedValue;
listItem.Update();
this.lblResult.Text = "发布成功";
}
catch (Exception ex)
{
this.lblResult.Text = "发布失败";
}
代码说明:BUG数据的增加,主要利用了SPListItem对象的Update方法来实现数据增加。同时此对象还有一个Delete的方法,用于删除数据用。
第四:扩展用户控件,让域用户能够查看自己的BUG数据。对于开发人员来说最理想的情况就是只显示自己的BUG数据。对于数据的查询我这里要用到SPQueyr对象的相关方法。下表是CAML查询的一些简单说明:
元素 | 说明 |
And | 并且 |
BeginsWith | 以某字符串开始的 |
Contains | 包含某字符串 |
Eq | 等于 |
FieldRef | 一个字段的引用 (在GroupBy 中使用) |
Geq | 大于等于 |
GroupBy | 分组 |
Gt | 大于 |
IsNotNull | 非空 |
IsNull | 空 |
Leq | 小于等于 |
Lt | 小于 |
Neq | 不等于 |
Now | 当前时间 |
Or | 或 |
OrderBy | 排序 |
Today | 今天的日期 |
TodayIso | 今天的日期(ISO格式) |
Where | Where子句 |
代码如下:
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 绑定BUG数据
/// </summary>
private void dbindMyBug()
{
SPWeb web = SPControl.GetContextSite(Context).RootWeb;
SPList list = web.Lists[sourceList];
SPQuery query = new SPQuery();
//检索所有的项目
query.ViewAttributes = "Scope='RecursiveAll'";
string cmal ="";
cmal = "<Where><Contains><FieldRef Name=\"sUser\" /><Value Type=\"User\">" + SPContext.Current.Web.CurrentUser.Name + "</Value></Contains></Where>";
query.Query = cmal;
int i = 1;
query.RowLimit = 100;
do
{
SPListItemCollection listItems = list.GetItems(query);
DataTable dr = listItems.GetDataTable();
this.GridView1.DataSource = dr;
this.GridView1.DataBind();
query.ListItemCollectionPosition = listItems.ListItemCollectionPosition;
i++;
}
while (query.ListItemCollectionPosition != null);
}
上面的查询主要应用了caml查询,如对这种语言不太熟悉的话,可能利用这个工具:U2U Caml Query Builde,具体怎样操作我就不帖图了,非常容易上手,感兴趣的朋友可以去网上搜索下。值的注意的是:
1:写caml查询语句中从Where标签开始就行,不要带上Query,因为系统在调用query.Query方法时会自己加上这个标签,如果在查询语句中包含了Qurey标签,则会出现查询结果错误的结果。
2:query.RowLimit的意思相当于SQL中的top n,取前多少条记录的意思。这个属性在做自定义分页时会非常有用。
3:query.ViewFields:查询结果中要显示的字段。例如:<FieldRef Name="sUser" />;
4:query.Query:查询条件,这里可以包含分组与排序条件。
总结:
本文利用一个简单的BUG系统的部分DEMO展示了利用用户控件来操作列表数据的过程。同时包含了WSS v3核心类的介绍,用户人员和组的添加,权限分配,caml语言简介及查询示例。