webParts与Web部件
web部件是ASP.NET WebForm里面的服務(wù)器控件,它涵蓋的內(nèi)容比較多,鑒于這種狀況的話鄙人不打算深究下去了,只是局限于了解web.config配置里面的配置內(nèi)容則可。
那么也得稍微說說啥是Web部件。引用MSDN的話:ASP.NET Web 部件是一組集成控件,用于創(chuàng)建網(wǎng)站使最終用戶可以直接從瀏覽器修改網(wǎng)頁的內(nèi)容、外觀和行為。這些修改可以應(yīng)用于網(wǎng)站上的所有用戶或個(gè)別用戶。還有引用它上面的插圖
看了這個(gè)之后我就感覺就類似于QQ個(gè)人空間上的各個(gè)面板或者OA系統(tǒng)上的面板,可以按照每個(gè)用戶的個(gè)人喜好去更改顯示的內(nèi)容,位置以及是否顯示
更多關(guān)于Web部件的內(nèi)容可參考本篇后面的參考的MSDN文章。關(guān)于Web部件的的WebPartManager和webParetZone就不說了,接下來則看看webParts配置節(jié)的內(nèi)容
配置分兩大塊,personalization的是關(guān)于個(gè)性化設(shè)置數(shù)據(jù)的提供以及用戶訪問權(quán)限的;另一個(gè)是關(guān)于web部件連接的時(shí)候數(shù)據(jù)結(jié)構(gòu)不一致需要轉(zhuǎn)換的配置。
下面則先看看personalization的,這個(gè)例子是參考了MSDN。實(shí)現(xiàn)的效果大概是記錄用戶個(gè)性化數(shù)據(jù),以及對數(shù)據(jù)的權(quán)限控制,本例子包含一個(gè)登錄頁面,一個(gè)示例頁面,兩個(gè)用戶控件。
首先示例頁面的內(nèi)容如下
登錄頁面只是包含了一個(gè)登錄控件
用于展現(xiàn)用戶個(gè)性化設(shè)置的自定義控件 Color
?
<%@ Control Language="C#" %><script runat="server">// User a field to reference the current WebPartManager. private WebPartManager _manager;// Defines personalized property for User scope. In this case, the property is// the background color of the text box. [Personalizable(PersonalizationScope.User)]public System.Drawing.Color UserColorChoice{get{return _coloruserTextBox.BackColor;}set{_coloruserTextBox.BackColor = value;}}// Defines personalized property for Shared scope. In this case, the property is// the background color of the text box. [Personalizable(PersonalizationScope.Shared) ]public System.Drawing.Color SharedColorChoice{get{return _colorsharedTextBox.BackColor;}set{_colorsharedTextBox.BackColor = value;}}void Page_Init(object sender, EventArgs e){_manager = WebPartManager.GetCurrentWebPartManager(Page); }protected void Page_Load(object src, EventArgs e) {// If Web Parts manager scope is User, hide the button that changes shared control.if (_manager.Personalization.Scope == PersonalizationScope.User){_sharedchangeButton.Visible = false;if (!_manager.Personalization.IsModifiable)_userchangeButton.Enabled = false;}else{_sharedchangeButton.Visible = true; if (!_manager.Personalization.IsModifiable){_sharedchangeButton.Enabled = false;_userchangeButton.Enabled = false;}} }// Changes color of the User text box background when button clicked by authorized user. protected void _userButton_Click(object src, EventArgs e){switch(_coloruserTextBox.BackColor.Name){case "Red":_coloruserTextBox.BackColor = System.Drawing.Color.Yellow;break;case "Yellow":_coloruserTextBox.BackColor = System.Drawing.Color.Green;break;case "Green":_coloruserTextBox.BackColor = System.Drawing.Color.Red;break;}}// Changes color of the Shared text box background when button clicked by authorized user. protected void _sharedButton_Click(object src, EventArgs e){switch (_colorsharedTextBox.BackColor.Name){case "Red":_colorsharedTextBox.BackColor = System.Drawing.Color.Yellow;break;case "Yellow":_colorsharedTextBox.BackColor = System.Drawing.Color.Green;break;case "Green":_colorsharedTextBox.BackColor = System.Drawing.Color.Red;break;} } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>WebParts Personalization Example</title> </head> <body> <p><asp:LoginName ID="LoginName1" runat="server" BorderWidth="500" BorderStyle="none" /><asp:LoginStatus ID="LoginStatus1" LogoutAction="RedirectToLoginPage" runat="server" /> </p><asp:Label ID="ScopeLabel" Text="Scoped Properties:" runat="server" Width="289px"></asp:Label><br /><table style="width: 226px"><tr><td><asp:TextBox ID="_coloruserTextBox" Font-Bold="True" Height="110px" runat="server" Text="User Property" BackColor="red" Width="110px" /> </td><td> <asp:TextBox ID="_colorsharedTextBox" runat="server" Height="110px" Width="110px" Text="Shared Property" BackColor="red" Font-Bold="true" /></td></tr><tr><td><asp:Button Text="Change User Color" ID="_userchangeButton" runat="server" OnClick="_userButton_Click" /></td><td ><asp:Button Text="Change Shared Color" ID="_sharedchangeButton" runat="server" OnClick="_sharedButton_Click" /></td></tr></table> </body> </html>?
?
? ?
用于顯示用戶個(gè)性化數(shù)據(jù)權(quán)限的自定義控件Persmode
?
1 <%@ control language="C#" %> 2 3 <script runat="server"> 4 5 // Use a field to reference the current WebPartManager. 6 private WebPartManager _manager; 7 8 protected void Page_Load(object src, EventArgs e) 9 { 10 // Get the current Web Parts manager. 11 _manager = WebPartManager.GetCurrentWebPartManager(Page); 12 13 // All radio buttons are disabled; the button settings show what the current state is. 14 EnterSharedRadioButton.Enabled = false; 15 ModifyStateRadioButton.Enabled = false; 16 17 // If Web Parts manager is in User scope, set scope button. 18 if (_manager.Personalization.Scope == PersonalizationScope.User) 19 UserScopeRadioButton.Checked = true; 20 else 21 SharedScopeRadioButton.Checked = true; 22 23 // Based on current user rights to enter Shared scope, set buttons. 24 if (_manager.Personalization.CanEnterSharedScope) 25 { 26 EnterSharedRadioButton.Checked = true; 27 No_Shared_Scope_Label.Visible = false; 28 Toggle_Scope_Button.Enabled = true; 29 } 30 else 31 { 32 EnterSharedRadioButton.Checked = false; 33 No_Shared_Scope_Label.Visible = true; 34 Toggle_Scope_Button.Enabled = false; 35 } 36 37 // Based on current user rights to modify personalization state, set buttons. 38 if (_manager.Personalization.IsModifiable) 39 { 40 ModifyStateRadioButton.Checked = true; 41 Reset_User_Button.Enabled = true; 42 } 43 else 44 { 45 ModifyStateRadioButton.Checked = false; 46 Reset_User_Button.Enabled = false; 47 } 48 } 49 // Resets all of a user and shared personalization data for the page. 50 protected void Reset_CurrentState_Button_Click(object src, EventArgs e) 51 { 52 // User must be authorized to modify state before a reset can occur. 53 //When in user scope, all users by default can change their own data. 54 if (_manager.Personalization.IsModifiable) 55 { 56 _manager.Personalization.ResetPersonalizationState(); 57 } 58 } 59 60 // Allows authorized user to change personalization scope. 61 protected void Toggle_Scope_Button_Click(object sender, EventArgs e) 62 { 63 if (_manager.Personalization.CanEnterSharedScope) 64 { 65 _manager.Personalization.ToggleScope(); 66 } 67 68 } 69 </script> 70 <div> 71 <asp:Panel ID="Panel1" runat="server" 72 Borderwidth="1" 73 Width="208px" 74 BackColor="lightgray" 75 Font-Names="Verdana, Arial, Sans Serif" Height="214px" > 76 <asp:Label ID="Label1" runat="server" 77 Text="Page Scope" 78 Font-Bold="True" 79 Font-Size="8pt" 80 Width="120px" /> <br /> 81 82 83 <asp:RadioButton ID="UserScopeRadioButton" runat="server" 84 Text="User" 85 AutoPostBack="true" 86 GroupName="Scope" 87 Enabled="false" /> 88 <asp:RadioButton ID="SharedScopeRadioButton" runat="server" 89 Text="Shared" 90 AutoPostBack="true" 91 GroupName="Scope" 92 Enabled="false" /> 93 <br /> 94 <asp:Label BorderStyle="None" Font-Bold="True" Font-Names="Courier New" ID="No_Shared_Scope_Label" Font-Size="Smaller" ForeColor="red" 95 runat="server" Visible="false" Width="179px">User cannot enter Shared scope</asp:Label> 96 <br /> 97 <asp:Label ID="Label2" runat="server" 98 Text="Current User Can:" 99 Font-Bold="True" 100 Font-Size="8pt" 101 Width="165px" /> 102 <br /> 103 <asp:RadioButton ID="ModifyStateRadioButton" runat="server" 104 Text="Modify State" Width="138px" /> 105 <br /> 106 <asp:RadioButton ID="EnterSharedRadioButton" runat="server" 107 Text="Enter Shared Scope" 108 AutoPostBack="true" /> <br /> 109 <br /> 110 <asp:Button ID="Toggle_Scope_Button" OnClick="Toggle_Scope_Button_Click" runat="server" 111 Text="Change Scope" Width="186px" /><br /> 112 <br /> 113 <asp:Button ID="Reset_User_Button" OnClick="Reset_CurrentState_Button_Click" runat="server" 114 Text="Reset Current Personalization" Width="185px" /></asp:Panel> 115 116 </div>?
?
?
最后少不了的就是在web.config中添加配置
在這里開始吹水了,首先MSDN上面例子沒提及到要添加認(rèn)證的配置,使得我最開始的時(shí)候登錄了還沒看到效果。后來在懷疑是需要配置認(rèn)證機(jī)制。接著這里使用了一個(gè)Provider,AspNetSqlPersonalizationProvider并非類名,只是SqlPersonalizationProvider配置的名稱而已。默認(rèn)配置如下,
在ASP.NET中實(shí)現(xiàn)了這個(gè)個(gè)性化提供者的就只有這個(gè)SqlPersonalizationProvider,這個(gè)我是看源碼還有MSDN中類的繼承結(jié)構(gòu)中看出來的。不知有無其他地方明確指出,如需要其他的提供機(jī)制,則需要自定義擴(kuò)展了。
您可以從其中?PersonalizationProvider?,并提供僅在此類中定義的抽象方法的實(shí)現(xiàn)。?抽象方法處理專門與保存和加載數(shù)據(jù)寫入物理數(shù)據(jù)存儲,以及數(shù)據(jù)存儲區(qū)管理。?自定義提供程序必須能夠處理可區(qū)分的方式的個(gè)性化信息?Shared?中的數(shù)據(jù)?User?數(shù)據(jù)。?此外,提供程序必須段個(gè)性化數(shù)據(jù)頁以及按應(yīng)用程序。
實(shí)現(xiàn)?PersonalizationProvider?緊密耦合的實(shí)現(xiàn)與?PersonalizationState?由于某些個(gè)性化設(shè)置提供程序方法返回的實(shí)例?PersonalizationState的派生類。?為了便于開發(fā)自定義提供程序,?PersonalizationProvider?基類包括個(gè)性化設(shè)置邏輯和序列化/反序列化邏輯,直接使用的默認(rèn)實(shí)現(xiàn)WebPartPersonalization?類。?結(jié)果是,創(chuàng)作專門用于使用不同的數(shù)據(jù)存儲區(qū)的自定義提供只需要下列抽象方法的實(shí)現(xiàn)︰
- GetCountOfState?-此方法需要能夠在數(shù)據(jù)庫中為提供的查詢參數(shù)的個(gè)性化數(shù)據(jù)行的數(shù)目進(jìn)行計(jì)數(shù)。
- LoadPersonalizationBlobs?-在給定路徑和用戶名的情況下,此方法從數(shù)據(jù)庫中加載兩個(gè)二進(jìn)制大型對象 (Blob): 一個(gè)用于共享的數(shù)據(jù),另一個(gè)用于用戶數(shù)據(jù)的 BLOB。?如果您提供的用戶名稱和路徑,則不需要?WebPartManager?控件,用于訪問可以提供的用戶文件名/路徑信息的頁信息。
- ResetPersonalizationBlob?-在給定路徑和用戶名的情況下,此方法中刪除數(shù)據(jù)庫中相應(yīng)的行。?如果您提供的用戶名稱和路徑,則不需要WebPartManager?控件,用于訪問可以提供的用戶文件名/路徑信息的頁信息。
- SavePersonalizationBlob?--此方法在給定的路徑和用戶名稱,保存對數(shù)據(jù)庫所提供的 BLOB。?如果您提供的用戶名稱和路徑,則不需要?WebPartManager?控件,用于訪問可以提供的用戶文件名/路徑信息的頁信息。
在所有這些方法中,如果只提供一個(gè)路徑,則表示正在操作頁上的共享的個(gè)性化設(shè)置數(shù)據(jù)。?如果用戶名和路徑傳遞到方法中,頁上的用戶個(gè)性化設(shè)置數(shù)據(jù)應(yīng)得到處理。?情況下?LoadPersonalizationBlobs, ,應(yīng)始終加載指定的路徑的共享的數(shù)據(jù),并 (可選) 的路徑的用戶個(gè)性化設(shè)置數(shù)據(jù)也如果應(yīng)加載的用戶名不是?null。
所有抽象方法旨在僅用于管理應(yīng)用程序,在運(yùn)行時(shí)不使用由 Web 部件基礎(chǔ)結(jié)構(gòu)。?個(gè)性化設(shè)置提供程序的實(shí)現(xiàn)的示例,請參閱SqlPersonalizationProvider?類。
說了這么多看看這個(gè)示例的運(yùn)行效果
經(jīng)過登錄之后就可以看到界面如上所示,點(diǎn)擊Change xxx Color就可以改變方塊的顏色,這些顏色設(shè)置是存儲到數(shù)據(jù)庫的,用戶可以在注銷下次登錄時(shí)扔看到這些設(shè)置,包括對面板的關(guān)閉和最小化操作。下面的面板是控制這些設(shè)置的作用域,一個(gè)是用戶個(gè)人的,一個(gè)是全局共享的。可以通過Change Scope去切換。這里涉及到兩個(gè)方面內(nèi)容,首先是數(shù)據(jù)保存,數(shù)據(jù)存儲在Web程序默認(rèn)建立的SqlServer數(shù)據(jù)庫中,與MemberShip的庫相同。個(gè)人數(shù)據(jù)的放在PersonalizationAllUsers里面,Share的則放在PersonalizationPerUser中。所有的數(shù)據(jù)都并非直接存放在表中,作為通用存儲的話這是不可能的。
另外關(guān)于權(quán)限控制的,在配置文件中的personalization/authorization配置節(jié)跟system.web/authorization的結(jié)構(gòu)很相像,區(qū)別在于verbs,這里用的值僅以下兩種。
對于獲取設(shè)置信息是不阻攔的,但是需要更換作用域進(jìn)入共享區(qū)時(shí)需要有enterSharedScope權(quán)限,當(dāng)需要更改任何一個(gè)作用域的數(shù)據(jù)時(shí)需要modeifyState。如果兩個(gè)權(quán)限都被deny的話,用戶就只能傻傻地看了
personalization的結(jié)束到此完,接下來到transformers。這里涉及到一個(gè)web部件連接的概念。不知我自己有否理解錯,這個(gè)web部件連接的雙方中提供數(shù)據(jù)的一方個(gè)人感覺就是一個(gè)數(shù)據(jù)源。數(shù)據(jù)源提供的數(shù)據(jù)可以給頁面上其他多個(gè)控件使用,但是數(shù)據(jù)源提供的數(shù)據(jù)格式不一定符合其他所有控件,因此這里就需要一個(gè)轉(zhuǎn)換器來適配雙方的差異,這就是適配器模式嘛!嗎?但是要是說多弄一個(gè)數(shù)據(jù)源(或者叫Provider)的話,這樣的開銷比較大。那么ASP.NET提供的轉(zhuǎn)換器就只有兩個(gè)RowToFieldTransformer和RowToParametersTransformer,如果需要其他的轉(zhuǎn)換就需要自己定義,還需要到配置文件中聲明一下這個(gè)轉(zhuǎn)換器,下面也是借鑒了一個(gè)MSDN的例子來嘗試一下通過一個(gè)行轉(zhuǎn)換到字符串。
對于MSDN的例子我還是精簡了兩個(gè)控件,大概可以看以下這里建立了一個(gè)靜態(tài)的Web部件連接,通過一個(gè)rowtostringtransformer進(jìn)行轉(zhuǎn)換。這個(gè)鏈接的提供者是rowproviderwebpart的自定義webPart,另一個(gè)stringconsumerwebpart的自定義webpart。這些類都定義在App_Code文件夾中,所以注冊命名空間的時(shí)候要注意一下
下面就是各個(gè)文件的代碼IString
RowToStringTransformer
? ?
下面這兩個(gè)類是參考了MSDN的代碼,自己根據(jù)當(dāng)前的情況改過一下,不然運(yùn)行不了,但不知道有否改錯,使之背離愿意
// This sample code creates a Web Parts control that acts as a provider // of row data. [AspNetHostingPermission(SecurityAction.Demand,Level = AspNetHostingPermissionLevel.Minimal)][AspNetHostingPermission(SecurityAction.InheritanceDemand,Level = AspNetHostingPermissionLevel.Minimal)]public sealed class RowProviderWebPart : WebPart, IWebPartRow{private DataTable _table;public RowProviderWebPart(){_table = new DataTable();DataColumn col = new DataColumn();col.DataType = typeof(string);col.ColumnName = "Name";_table.Columns.Add(col);col = new DataColumn();col.DataType = typeof(string);col.ColumnName = "Address";_table.Columns.Add(col);col = new DataColumn();col.DataType = typeof(int);col.ColumnName = "ZIP Code";_table.Columns.Add(col);DataRow row = _table.NewRow();row["Name"] = "John Q. Public";row["Address"] = "123 Main Street";row["ZIP Code"] = 98000;_table.Rows.Add(row);}[ConnectionProvider("String123")]public IWebPartRow GetConnection(){return new RowProviderWebPart();}public PropertyDescriptorCollection Schema{get{return TypeDescriptor.GetProperties(_table.DefaultView[0]);}}public void GetRowData(RowCallback callback){foreach (var item in _table.DefaultView){callback(item);}}} [AspNetHostingPermission(SecurityAction.Demand,Level = AspNetHostingPermissionLevel.Minimal)][AspNetHostingPermission(SecurityAction.InheritanceDemand,Level = AspNetHostingPermissionLevel.Minimal)]public sealed class StringConsumerWebpart : WebPart{private IString _provider;private string _stringData;private void GetRowData(object rowData){_stringData = rowData.ToString();}protected override void OnPreRender(EventArgs e){if (_provider != null){_provider.GetStringValue(new StringCallback(GetRowData));}}protected override void RenderContents(HtmlTextWriter writer){if (!string.IsNullOrEmpty(_stringData)){writer.Write(_stringData);writer.WriteBreak();writer.WriteLine();}else{writer.Write("No data");}}[ConnectionConsumer("String123")]public void SetConnection(IString provider){_provider = provider;}}?
在調(diào)試的時(shí)候發(fā)現(xiàn)_provider.GetStringValue(new StringCallback(GetRowData));這行代碼最繞,嵌了幾個(gè)委托;另外有個(gè)有意思的地方就是get/set連接的時(shí)候,它使用了一個(gè)類似依賴注入的東西,Attribute的Display參數(shù)把Connection的get/set兩個(gè)方法配對,完全忽略方法的命名,可惜這個(gè)ConnectionConsumer和ConnectionProvider只能描述方法,不然可以用到屬性去。
差點(diǎn)忘了把Web.config的配置添加進(jìn)去
最終結(jié)果如下圖,就把Provider中的一個(gè)table的專成了一個(gè)字符串。
? ?
參考文章
? ?
Visual Studio 中的 ASP.NET Web 部件
來自 <https://msdn.microsoft.com/zh-cn/library/0ey99zzh(v=vs.80).aspx>
? ?
ASP.NET Web 部件概述
來自 <https://msdn.microsoft.com/zh-cn/library/hhy9ewf1(v=vs.100).aspx>
? ?
Web 部件控件集概述
來自 <https://msdn.microsoft.com/zh-cn/library/k3w2y2tf(v=vs.100).aspx>
? ?
Web 部件個(gè)性化設(shè)置概述
來自 <https://msdn.microsoft.com/zh-cn/library/z36h8be9(v=vs.100).aspx>
? ?
webParts 元素(ASP.NET 設(shè)置架構(gòu))
來自 <https://msdn.microsoft.com/zh-cn/library/ms164680(v=vs.110).aspx>
? ?
WebPartPersonalization 類(Personlization設(shè)置實(shí)現(xiàn))
來自 <https://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.webparts.webpartpersonalization(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-4>
? ?
WebPartTransformer 類(transformers設(shè)置實(shí)現(xiàn))
來自 <https://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.webparts.webparttransformer(v=vs.110).aspx>
? ?
如何:聲明兩個(gè) Web 部件控件之間的靜態(tài)連接
來自 <https://msdn.microsoft.com/zh-cn/library/ms178188(v=vs.100).aspx>
? ?
IWebPartRow 接口
來自 <https://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.webparts.iwebpartrow(v=vs.100).aspx>
? ?
? ?
總結(jié)
以上是生活随笔為你收集整理的webParts与Web部件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XMNetworking 网络库的设计与
- 下一篇: bash特性之四、五