您的位置:首页 > 其它

MOSS字段编辑权限控制方案的实现(1)-管理页面的开发和配置信息的持久化

2008-09-01 13:31 1221 查看
MOSS字段编辑权限控制方案的实现(1)-管理页面的开发和配置信息的持久化 MOSS字段编辑权限控制方案,实现了控制列表项,或文档属性的字段级权限控制,本篇讲述如何开发配置页面以及如何将配置信息持久化。

我们先看一下配置界面的样子:



wss(moss)的所有配置页面都放到C:/Program Files/Common Files/Microsoft Shared/web server extensions/12/TEMPLATE/LAYOUTS目录
或子目录中,我们将字段权限配置页面(FieldEditControl.aspx)放到Layouts的子目录CodeArt中。
配置界面的核心逻辑开发成一个webcontrol(FieldRightSettingPart),将这个webpart直接嵌入到管理页面,管理页面的代码如下:




<%

@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>




<%

@ Page Language="C#" Inherits="Microsoft.SharePoint.ApplicationPages.NewListPage" MasterPageFile="~/_layouts/application.master" %>




<%

@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %> <%

@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%

@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%

@ Import Namespace="Microsoft.SharePoint" %>




<%

@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>




<%

@ Register Assembly="CodeArt.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2c606279787b575f" Namespace="CodeArt.SharePoint.WebPart" TagPrefix="codeArt" %>


<asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">


列表字段权限设置


</asp:Content>


<asp:Content ID="Content6" ContentPlaceHolderId="PlaceHolderMain" runat="server">



<codeArt:FieldRightSettingPart runat="server" id="fSetting" />



</asp:Content>
wss开发中经常会碰到配置信息存储的问题,如果是webpart,我们可以用webpart的属性来存储,其他情况下,我们可以考虑用数据库或List来存储。
这里我选择用文档库来存储,将配置类序列化成xml存储到一个文档库中。考虑到以后还会碰到这类配置信息存储的情况,把这个功能开发成一个通用的类CongfigManager:(为了以后“可能的”替换数据存储方式,用了工程模式)






ConfigManager 的代码


public abstract class ConfigManager






{




public static ConfigManager GetConfigManager(string key)






{


return new DocLibConfigManager( key );


}




public virtual T GetConfigData<T>(Guid id) where T : class , new()






{


object obj = this.GetConfigData(typeof(T), id);




if( obj == null )


return null;


return


(T)obj;


}




public virtual object GetConfigData(Type t, Guid id)






{


return null ;


}




public virtual void SetConfigData(Guid id , object obj)






{




}




public virtual void ClearConfigData(Guid id)






{


}


}




ConfigManager实现类DocLibConfigManager的代码


class DocLibConfigManager : ConfigManager






{


private string _key;


public DocLibConfigManager(string key)






{


_key = key;


}




SPList EnsureList(SPWeb web)






{


SPList list = null;




try






{


list = web.Lists[_key];


}




catch

{ }




if (list == null)






{


web.AllowUnsafeUpdates = true;


Guid listId = web.Lists.Add(_key, "List for config , never delete this list.", SPListTemplateType.DocumentLibrary);


list = web.Lists[listId];


}




return list;


}




public override void SetConfigData( Guid id ,object obj)






{


SPList list = null;




string xml = SerializeUtil.Seralize(obj);


byte[] content = Encoding.UTF8.GetBytes(xml);




SPSecurity.RunWithElevatedPrivileges(delegate()






{


using (SPSite elevatedsiteColl = new SPSite(SPContext.Current.Site.ID))






{


using (SPWeb elevatedWeb = elevatedsiteColl.OpenWeb(SPContext.Current.Web.ID))






{


list = this.EnsureList(elevatedWeb);


elevatedWeb.AllowUnsafeUpdates = true;


SPFile file = list.RootFolder.Files.Add( id.ToString() + ".xml", content, true);


}


}


});




}




private SPListItem GetItem(SPList list, Guid id)






{


SPQuery q = new SPQuery();


q.Query = "<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>" + id.ToString() + ".xml</Value></Eq></Where>";


q.RowLimit = 1;




SPListItemCollection items = list.GetItems(q);




if (items.Count == 0)


return null;


else


return items[0];


}




public override void ClearConfigData(Guid id)






{


SPSecurity.RunWithElevatedPrivileges(delegate()






{


using (SPSite elevatedsiteColl = new SPSite(SPContext.Current.Site.ID))






{


using (SPWeb elevatedWeb = elevatedsiteColl.OpenWeb(SPContext.Current.Web.ID))






{


try






{


SPList list = this.EnsureList(elevatedWeb);


elevatedWeb.AllowUnsafeUpdates = true;




SPListItem item = this.GetItem(list, id);


if( item != null )


item.Delete();


}




catch

{ throw; }


}


}


});




}




public override object GetConfigData(Type t, Guid id)






{


object obj = null;




SPSecurity.RunWithElevatedPrivileges(delegate()






{


using (SPSite elevatedsiteColl = new SPSite(SPContext.Current.Site.ID))






{


using (SPWeb elevatedWeb = elevatedsiteColl.OpenWeb(SPContext.Current.Web.ID))






{


SPList list = this.EnsureList(elevatedWeb);




try






{


SPListItem item = this.GetItem(list, id);




if (item != null)






{


SPFile file = item.File;




XmlDocument doc = new XmlDocument();


doc.Load(item.File.OpenBinaryStream());




obj = SerializeUtil.Deserialize(t, doc.OuterXml);


}


}




catch

{ throw; }


}


}


});




return obj;


}


}
这个CongfigManager实现了对一个配置类的保存,获取和删除。

下面考虑配置类如何抽象化
用以下类来表示每个字段的配置信息:


[Serializable]


public class FieldEditSetting






{


public string FieldName;




public bool CreatorCanEdit;




public bool AllUserCanEdit ;




public string SpecialAccounts;




public bool IsInSpecialAccounts(string account)






{


if (String.IsNullOrEmpty(SpecialAccounts))


return false;




string checkList = "," + this.SpecialAccounts.ToLower() + ",";




return checkList.IndexOf("," + account.ToLower() + ",") != -1;


}




public bool CanEdit( SPUser currentUser , SPUser creatUser )






{


//if (currentUser.IsSiteAdmin) return true;




if (this.AllUserCanEdit) return true;




if (this.CreatorCanEdit && String.Compare(currentUser.LoginName, creatUser.LoginName, true) == 0)


return true;




return this.IsInSpecialAccounts(currentUser.LoginName);


}


}用一个集合类来表示整个列表的所有字段的配置信息(本来想用字典的,单字典类型不能序列化,这能放弃):


[Serializable]


public class ListFieldEditSetting : List<FieldEditSetting>






{


public const string Config_List = "__CodeArt_ListFieldEditSetting";




public FieldEditSetting GetByFieldName(string fieldName)






{


foreach (FieldEditSetting fSetting in this)






{


if (String.Compare(fSetting.FieldName, fieldName, true) == 0)


return fSetting;


}



return null;


}




public void Save(Guid listId)






{


ConfigManager cmg = ConfigManager.GetConfigManager(ListFieldEditSetting.Config_List);


cmg.SetConfigData(listId, this);


}





public static ListFieldEditSetting GetListSetting(Guid listId)






{


ConfigManager cmg = ConfigManager.GetConfigManager(ListFieldEditSetting.Config_List);




ListFieldEditSetting setting = cmg.GetConfigData<ListFieldEditSetting>(listId);




return setting;


}


}
以上的基础类建好了,可以开始FieldRightSettingPart的开发了:




FieldRightSettingPart 的代码


public class FieldRightSettingPart : BaseSPListWebPart






{


private Button _btnSubmit;


private Table _layoutTable;




private Dictionary<string, CheckBox> _AllUserCanEditControls = new Dictionary<string, CheckBox>();


private Dictionary<string, CheckBox> _CreatorCanEditControls = new Dictionary<string, CheckBox>();


private Dictionary<string, Microsoft.SharePoint.WebControls.PeopleEditor> _SpecialAccountsControls =


new Dictionary<string, Microsoft.SharePoint.WebControls.PeopleEditor>();




protected override void CreateChildControls()






{


if (List == null)


return;




_layoutTable = new Table ();


_layoutTable.BorderWidth = new Unit("0px");


_layoutTable.CssClass = "ms-formtable";


_layoutTable.CellSpacing = 0;




this.Controls.Add(_layoutTable);


this.AddRow(_layoutTable, "<b>字段</b>", "<b>编辑权限</b>");




//


ConfigManager cmg = ConfigManager.GetConfigManager(ListFieldEditSetting.Config_List);




ListFieldEditSetting setting = cmg.GetConfigData<ListFieldEditSetting>(List.ID);




//


foreach (SPField f in List.Fields)






{


if (f.Hidden || f.ReadOnlyField ) continue ;




TableRow row = new TableRow();


_layoutTable.Rows.Add(row);


TableCell fieldCell = new TableCell();


fieldCell.VerticalAlign = VerticalAlign.Top;


fieldCell.CssClass = "ms-formlabel";


row.Cells.Add(fieldCell);




fieldCell.Text = f.Title + f.AuthoringInfo;




TableCell ctlCell = new TableCell();


ctlCell.VerticalAlign = VerticalAlign.Top;


ctlCell.CssClass = "ms-formbody";


row.Cells.Add(ctlCell);




CheckBox allUser = new CheckBox();


allUser.Text = "所有人员";


allUser.Checked = true;


ctlCell.Controls.Add(allUser);


this.AddHtml("<br/>", ctlCell);




_AllUserCanEditControls.Add(f.InternalName, allUser);




CheckBox creator = new CheckBox();


creator.Text = "创建者";


creator.Checked = true;


ctlCell.Controls.Add(creator);


this.AddHtml("<br/>", ctlCell);




_CreatorCanEditControls.Add(f.InternalName, creator);




this.AddHtml("指定人员:<br/>", ctlCell );


Microsoft.SharePoint.WebControls.PeopleEditor peopleEditor = new Microsoft.SharePoint.WebControls.PeopleEditor();


peopleEditor.MultiSelect = true;


peopleEditor.Rows = 1;


peopleEditor.Width = new Unit("200px");


ctlCell.Controls.Add(peopleEditor);




_SpecialAccountsControls.Add(f.InternalName, peopleEditor);




this.SetControlValue(allUser, creator, peopleEditor, setting, f.InternalName);


}




_btnSubmit = new Button();


_btnSubmit.ID = "btn1";


_btnSubmit.Text = "确定";


_btnSubmit.CssClass = "ms-ButtonHeightWidth";


this.Controls.Add(_btnSubmit);


_btnSubmit.Click += new EventHandler(_btnSubmit_Click);




}




void SetControlValue(CheckBox allUser, CheckBox creator, Microsoft.SharePoint.WebControls.PeopleEditor peopleEditor ,ListFieldEditSetting setting , string fieldName )






{


if (setting == null || setting.Count == 0 || Page.IsPostBack )


return ;




FieldEditSetting set = setting.GetByFieldName(fieldName);




if (set == null) return;




allUser.Checked = set.AllUserCanEdit;


creator.Checked = set.CreatorCanEdit;


peopleEditor.CommaSeparatedAccounts = set.SpecialAccounts;


}






void _btnSubmit_Click(object sender, EventArgs e)






{


ListFieldEditSetting setting = new ListFieldEditSetting();




foreach (SPField f in List.Fields)






{


if (f.Hidden || f.ReadOnlyField) continue;




FieldEditSetting set = new FieldEditSetting();


setting.Add(set);




set.FieldName = f.InternalName.ToLower();




CheckBox allUser = _AllUserCanEditControls[f.InternalName];




set.AllUserCanEdit = allUser.Checked;




CheckBox creator = _CreatorCanEditControls[f.InternalName];




set.CreatorCanEdit = creator.Checked;




Microsoft.SharePoint.WebControls.PeopleEditor peopleEditor = _SpecialAccountsControls[f.InternalName];




set.SpecialAccounts = peopleEditor.CommaSeparatedAccounts;


}




setting.Save(base.List.ID);




if (Page.Request.QueryString["ListId"] != null)






{


string sourceUrl = base.Web.ServerRelativeUrl + "_layouts/listedit.aspx?List=" + base.List.ID.ToString("B").ToUpper();


Page.Response.Redirect(sourceUrl);


}




//ConfigManager cmg = ConfigManager.GetConfigManager(ListFieldEditSetting.Config_List);


//cmg.SetConfigData(List.ID, setting);


}




//void AddRow( Table table , params Control[] ctls)


//{


// TableRow row = new TableRow();


// table.Rows.Add(row);




// foreach (Control c in ctls)


// {


// TableCell cell = new TableCell();


// row.Cells.Add(cell);


// cell.Controls.Add(c);


// }


//}




void AddRow(Table table, params string[] texts)






{


TableRow row = new TableRow();


table.Rows.Add(row);




foreach (string c in texts)






{


TableCell cell = new TableCell();


row.Cells.Add(cell);


cell.Text = c;


}


}


}
FieldRightSettingPart会在内部生成一个布局表格和很多的子控件,为了便于操作这些子 控件,
声明了三个字典类型的变量,来放置生成的控件,字典key为字段名,值为对应的编辑控件:


private Dictionary<string, CheckBox> _AllUserCanEditControls = new Dictionary<string, CheckBox>();


private Dictionary<string, CheckBox> _CreatorCanEditControls = new Dictionary<string, CheckBox>();


private Dictionary<string, Microsoft.SharePoint.WebControls.PeopleEditor> _SpecialAccountsControls =


new Dictionary<string, Microsoft.SharePoint.WebControls.PeopleEditor>();在CreateChildControls,遍历列表的字段,生成设置界面,同时若已经存在配置信息,则按照配置信息初始化控件初始值:




CreateChildControls


protected override void CreateChildControls()






{


if (List == null)


return;




_layoutTable = new Table ();


_layoutTable.BorderWidth = new Unit("0px");


_layoutTable.CssClass = "ms-formtable";


_layoutTable.CellSpacing = 0;




this.Controls.Add(_layoutTable);


this.AddRow(_layoutTable, "<b>字段</b>", "<b>编辑权限</b>");




//


ConfigManager cmg = ConfigManager.GetConfigManager(ListFieldEditSetting.Config_List);




ListFieldEditSetting setting = cmg.GetConfigData<ListFieldEditSetting>(List.ID);




//


foreach (SPField f in List.Fields)






{


if (f.Hidden || f.ReadOnlyField ) continue ;




TableRow row = new TableRow();


_layoutTable.Rows.Add(row);


TableCell fieldCell = new TableCell();


fieldCell.VerticalAlign = VerticalAlign.Top;


fieldCell.CssClass = "ms-formlabel";


row.Cells.Add(fieldCell);




fieldCell.Text = f.Title + f.AuthoringInfo;




TableCell ctlCell = new TableCell();


ctlCell.VerticalAlign = VerticalAlign.Top;


ctlCell.CssClass = "ms-formbody";


row.Cells.Add(ctlCell);




CheckBox allUser = new CheckBox();


allUser.Text = "所有人员";


allUser.Checked = true;


ctlCell.Controls.Add(allUser);


this.AddHtml("<br/>", ctlCell);




_AllUserCanEditControls.Add(f.InternalName, allUser);




CheckBox creator = new CheckBox();


creator.Text = "创建者";


creator.Checked = true;


ctlCell.Controls.Add(creator);


this.AddHtml("<br/>", ctlCell);




_CreatorCanEditControls.Add(f.InternalName, creator);




this.AddHtml("指定人员:<br/>", ctlCell );


Microsoft.SharePoint.WebControls.PeopleEditor peopleEditor = new Microsoft.SharePoint.WebControls.PeopleEditor();


peopleEditor.MultiSelect = true;


peopleEditor.Rows = 1;


peopleEditor.Width = new Unit("200px");


ctlCell.Controls.Add(peopleEditor);




_SpecialAccountsControls.Add(f.InternalName, peopleEditor);




this.SetControlValue(allUser, creator, peopleEditor, setting, f.InternalName);


}




_btnSubmit = new Button();


_btnSubmit.ID = "btn1";


_btnSubmit.Text = "确定";


_btnSubmit.CssClass = "ms-ButtonHeightWidth";


this.Controls.Add(_btnSubmit);


_btnSubmit.Click += new EventHandler(_btnSubmit_Click);




}
按钮提交时,遍历编辑子控件,组装配置类,调用ConfigManage类保存数据。:




_btnSubmit_Click


void _btnSubmit_Click(object sender, EventArgs e)






{


ListFieldEditSetting setting = new ListFieldEditSetting();




foreach (SPField f in List.Fields)






{


if (f.Hidden || f.ReadOnlyField) continue;




FieldEditSetting set = new FieldEditSetting();


setting.Add(set);




set.FieldName = f.InternalName.ToLower();




CheckBox allUser = _AllUserCanEditControls[f.InternalName];




set.AllUserCanEdit = allUser.Checked;




CheckBox creator = _CreatorCanEditControls[f.InternalName];




set.CreatorCanEdit = creator.Checked;




Microsoft.SharePoint.WebControls.PeopleEditor peopleEditor = _SpecialAccountsControls[f.InternalName];




set.SpecialAccounts = peopleEditor.CommaSeparatedAccounts;


}




setting.Save(base.List.ID);




if (Page.Request.QueryString["ListId"] != null)






{


string sourceUrl = base.Web.ServerRelativeUrl + "_layouts/listedit.aspx?List=" + base.List.ID.ToString("B").ToUpper();


Page.Response.Redirect(sourceUrl);


}


}
game over!

附1:存放配置信息的文档库:



附2:配置信息序列化后的xml格式:


<?xml version="1.0" encoding="utf-8"?>


<ArrayOfFieldEditSetting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">


<FieldEditSetting>


<FieldName>fileleafref</FieldName>


<CreatorCanEdit>false</CreatorCanEdit>


<AllUserCanEdit>false</AllUserCanEdit>


<SpecialAccounts /></FieldEditSetting>


<FieldEditSetting>


<FieldName>title</FieldName>


<CreatorCanEdit>false</CreatorCanEdit>


<AllUserCanEdit>false</AllUserCanEdit>


<SpecialAccounts /></FieldEditSetting>


</ArrayOfFieldEditSetting>

本系列的所有文章:
CodeArt WSS3.0(MOSS)字段编辑权限控制解决方案(v1.0)
CodeArt WSS3.0(MOSS)字段编辑权限控制解决方案的实现 -- 概要
MOSS字段编辑权限控制方案的实现(1)-管理页面的开发和配置信息的持久化
WSS页面定制系列(2)---定制单个列表的表单页面
WSS页面定制系列(3)---重写表单的保存逻辑
MOSS字段编辑权限控制方案(4)-打包解决方案
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: