web部件是ASP.NET WebForm里面的服务器控件,它涵盖的内容比较多,鉴于这种状况的话鄙人不打算深究下去了,只是局限于了解web.config配置里面的配置内容则可。

那么也得稍微说说啥是Web部件。引用MSDN的话:ASP.NET Web 部件是一组集成控件,用于创建网站使最终用户可以直接从浏览器修改网页的内容、外观和行为。这些修改可以应用于网站上的所有用户或个别用户。还有引用它上面的插图

看了这个之后我就感觉就类似于QQ个人空间上的各个面板或者OA系统上的面板,可以按照每个用户的个人喜好去更改显示的内容,位置以及是否显示

更多关于Web部件的内容可参考本篇后面的参考的MSDN文章。关于Web部件的的WebPartManager和webParetZone就不说了,接下来则看看webParts配置节的内容

配置分两大块,personalization的是关于个性化设置数据的提供以及用户访问权限的;另一个是关于web部件连接的时候数据结构不一致需要转换的配置。

下面则先看看personalization的,这个例子是参考了MSDN。实现的效果大概是记录用户个性化数据,以及对数据的权限控制,本例子包含一个登录页面,一个示例页面,两个用户控件。

首先示例页面的内容如下

登录页面只是包含了一个登录控件

用于展现用户个性化设置的自定义控件 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>

用于显示用户个性化数据权限的自定义控件Persmode

 <%@ control language="C#" %>

 <script runat="server">

  // Use a field to reference the current WebPartManager.
private WebPartManager _manager; protected void Page_Load(object src, EventArgs e)
{
// Get the current Web Parts manager.
_manager = WebPartManager.GetCurrentWebPartManager(Page); // All radio buttons are disabled; the button settings show what the current state is.
EnterSharedRadioButton.Enabled = false;
ModifyStateRadioButton.Enabled = false; // If Web Parts manager is in User scope, set scope button.
if (_manager.Personalization.Scope == PersonalizationScope.User)
UserScopeRadioButton.Checked = true;
else
SharedScopeRadioButton.Checked = true; // Based on current user rights to enter Shared scope, set buttons.
if (_manager.Personalization.CanEnterSharedScope)
{
EnterSharedRadioButton.Checked = true;
No_Shared_Scope_Label.Visible = false;
Toggle_Scope_Button.Enabled = true;
}
else
{
EnterSharedRadioButton.Checked = false;
No_Shared_Scope_Label.Visible = true;
Toggle_Scope_Button.Enabled = false;
} // Based on current user rights to modify personalization state, set buttons.
if (_manager.Personalization.IsModifiable)
{
ModifyStateRadioButton.Checked = true;
Reset_User_Button.Enabled = true;
}
else
{
ModifyStateRadioButton.Checked = false;
Reset_User_Button.Enabled = false;
}
}
// Resets all of a user and shared personalization data for the page.
protected void Reset_CurrentState_Button_Click(object src, EventArgs e)
{
// User must be authorized to modify state before a reset can occur.
//When in user scope, all users by default can change their own data.
if (_manager.Personalization.IsModifiable)
{
_manager.Personalization.ResetPersonalizationState();
}
} // Allows authorized user to change personalization scope.
protected void Toggle_Scope_Button_Click(object sender, EventArgs e)
{
if (_manager.Personalization.CanEnterSharedScope)
{
_manager.Personalization.ToggleScope();
} }
</script>
<div>
&nbsp;<asp:Panel ID="Panel1" runat="server"
Borderwidth="1"
Width="208px"
BackColor="lightgray"
Font-Names="Verdana, Arial, Sans Serif" Height="214px" >
<asp:Label ID="Label1" runat="server"
Text="Page Scope"
Font-Bold="True"
Font-Size="8pt"
Width="120px" />&nbsp;<br /> <asp:RadioButton ID="UserScopeRadioButton" runat="server"
Text="User"
AutoPostBack="true"
GroupName="Scope"
Enabled="false" />
<asp:RadioButton ID="SharedScopeRadioButton" runat="server"
Text="Shared"
AutoPostBack="true"
GroupName="Scope"
Enabled="false" />
<br />
<asp:Label BorderStyle="None" Font-Bold="True" Font-Names="Courier New" ID="No_Shared_Scope_Label" Font-Size="Smaller" ForeColor="red"
runat="server" Visible="false" Width="179px">User cannot enter Shared scope</asp:Label>
<br />
<asp:Label ID="Label2" runat="server"
Text="Current User Can:"
Font-Bold="True"
Font-Size="8pt"
Width="165px" />
<br />
<asp:RadioButton ID="ModifyStateRadioButton" runat="server"
Text="Modify State" Width="138px" />
<br />
<asp:RadioButton ID="EnterSharedRadioButton" runat="server"
Text="Enter Shared Scope"
AutoPostBack="true" />&nbsp;<br />
<br />
<asp:Button ID="Toggle_Scope_Button" OnClick="Toggle_Scope_Button_Click" runat="server"
Text="Change Scope" Width="186px" /><br />
<br />
<asp:Button ID="Reset_User_Button" OnClick="Reset_CurrentState_Button_Click" runat="server"
Text="Reset Current Personalization" Width="185px" /></asp:Panel>
&nbsp; &nbsp;
</div>

最后少不了的就是在web.config中添加配置

在这里开始吹水了,首先MSDN上面例子没提及到要添加认证的配置,使得我最开始的时候登录了还没看到效果。后来在怀疑是需要配置认证机制。接着这里使用了一个Provider,AspNetSqlPersonalizationProvider并非类名,只是SqlPersonalizationProvider配置的名称而已。默认配置如下,

在ASP.NET中实现了这个个性化提供者的就只有这个SqlPersonalizationProvider,这个我是看源码还有MSDN中类的继承结构中看出来的。不知有无其他地方明确指出,如需要其他的提供机制,则需要自定义扩展了。

您可以从其中 PersonalizationProvider ,并提供仅在此类中定义的抽象方法的实现。 抽象方法处理专门与保存和加载数据写入物理数据存储,以及数据存储区管理。 自定义提供程序必须能够处理可区分的方式的个性化信息 Shared 中的数据 User 数据。 此外,提供程序必须段个性化数据页以及按应用程序。

实现 PersonalizationProvider 紧密耦合的实现与 PersonalizationState 由于某些个性化设置提供程序方法返回的实例 PersonalizationState的派生类。 为了便于开发自定义提供程序, PersonalizationProvider 基类包括个性化设置逻辑和序列化/反序列化逻辑,直接使用的默认实现WebPartPersonalization 类。 结果是,创作专门用于使用不同的数据存储区的自定义提供只需要下列抽象方法的实现︰

  • GetCountOfState -此方法需要能够在数据库中为提供的查询参数的个性化数据行的数目进行计数。
  • LoadPersonalizationBlobs -在给定路径和用户名的情况下,此方法从数据库中加载两个二进制大型对象 (Blob): 一个用于共享的数据,另一个用于用户数据的 BLOB。 如果您提供的用户名称和路径,则不需要 WebPartManager 控件,用于访问可以提供的用户文件名/路径信息的页信息。
  • ResetPersonalizationBlob -在给定路径和用户名的情况下,此方法中删除数据库中相应的行。 如果您提供的用户名称和路径,则不需要WebPartManager 控件,用于访问可以提供的用户文件名/路径信息的页信息。
  • SavePersonalizationBlob --此方法在给定的路径和用户名称,保存对数据库所提供的 BLOB。 如果您提供的用户名称和路径,则不需要 WebPartManager 控件,用于访问可以提供的用户文件名/路径信息的页信息。

在所有这些方法中,如果只提供一个路径,则表示正在操作页上的共享的个性化设置数据。 如果用户名和路径传递到方法中,页上的用户个性化设置数据应得到处理。 情况下 LoadPersonalizationBlobs, ,应始终加载指定的路径的共享的数据,并 (可选) 的路径的用户个性化设置数据也如果应加载的用户名不是 null

所有抽象方法旨在仅用于管理应用程序,在运行时不使用由 Web 部件基础结构。 个性化设置提供程序的实现的示例,请参阅SqlPersonalizationProvider 类。

说了这么多看看这个示例的运行效果

经过登录之后就可以看到界面如上所示,点击Change xxx Color就可以改变方块的颜色,这些颜色设置是存储到数据库的,用户可以在注销下次登录时扔看到这些设置,包括对面板的关闭和最小化操作。下面的面板是控制这些设置的作用域,一个是用户个人的,一个是全局共享的。可以通过Change Scope去切换。这里涉及到两个方面内容,首先是数据保存,数据存储在Web程序默认建立的SqlServer数据库中,与MemberShip的库相同。个人数据的放在PersonalizationAllUsers里面,Share的则放在PersonalizationPerUser中。所有的数据都并非直接存放在表中,作为通用存储的话这是不可能的。

另外关于权限控制的,在配置文件中的personalization/authorization配置节跟system.web/authorization的结构很相像,区别在于verbs,这里用的值仅以下两种。

对于获取设置信息是不阻拦的,但是需要更换作用域进入共享区时需要有enterSharedScope权限,当需要更改任何一个作用域的数据时需要modeifyState。如果两个权限都被deny的话,用户就只能傻傻地看了

personalization的结束到此完,接下来到transformers。这里涉及到一个web部件连接的概念。不知我自己有否理解错,这个web部件连接的双方中提供数据的一方个人感觉就是一个数据源。数据源提供的数据可以给页面上其他多个控件使用,但是数据源提供的数据格式不一定符合其他所有控件,因此这里就需要一个转换器来适配双方的差异,这就是适配器模式嘛!吗?但是要是说多弄一个数据源(或者叫Provider)的话,这样的开销比较大。那么ASP.NET提供的转换器就只有两个RowToFieldTransformer和RowToParametersTransformer,如果需要其他的转换就需要自己定义,还需要到配置文件中声明一下这个转换器,下面也是借鉴了一个MSDN的例子来尝试一下通过一个行转换到字符串。

对于MSDN的例子我还是精简了两个控件,大概可以看以下这里建立了一个静态的Web部件连接,通过一个rowtostringtransformer进行转换。这个链接的提供者是rowproviderwebpart的自定义webPart,另一个stringconsumerwebpart的自定义webpart。这些类都定义在App_Code文件夹中,所以注册命名空间的时候要注意一下

下面就是各个文件的代码IString

RowToStringTransformer

下面这两个类是参考了MSDN的代码,自己根据当前的情况改过一下,不然运行不了,但不知道有否改错,使之背离愿意

    // 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"] = ;
_table.Rows.Add(row);
} [ConnectionProvider("String123")]
public IWebPartRow GetConnection()
{
return new RowProviderWebPart();
} public PropertyDescriptorCollection Schema
{
get
{
return TypeDescriptor.GetProperties(_table.DefaultView[]);
}
} 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;
}
}

在调试的时候发现_provider.GetStringValue(new StringCallback(GetRowData));这行代码最绕,嵌了几个委托;另外有个有意思的地方就是get/set连接的时候,它使用了一个类似依赖注入的东西,Attribute的Display参数把Connection的get/set两个方法配对,完全忽略方法的命名,可惜这个ConnectionConsumer和ConnectionProvider只能描述方法,不然可以用到属性去。

差点忘了把Web.config的配置添加进去

最终结果如下图,就把Provider中的一个table的专成了一个字符串。

参考文章

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 部件个性化设置概述

来自 <https://msdn.microsoft.com/zh-cn/library/z36h8be9(v=vs.100).aspx>

webParts 元素(ASP.NET 设置架构)

来自 <https://msdn.microsoft.com/zh-cn/library/ms164680(v=vs.110).aspx>

WebPartPersonalization 类(Personlization设置实现)

来自 <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设置实现)

来自 <https://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.webparts.webparttransformer(v=vs.110).aspx>

如何:声明两个 Web 部件控件之间的静态连接

来自 <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>

webParts与Web部件的更多相关文章

  1. “此网页上的某个 Web 部件或 Web 表单控件无法显示或导入。找不到该类型,或该类型未注册为安全类型。”

    自从vs装了Resharper,看见提示总是手贱的想去改掉它.于是乎手一抖,把一个 可视web部件的命名空间给改了. 喏,从LibrarySharePoint.WebPart.LibraryAddEd ...

  2. SharePoint Framework 在web部件中使用第三方样式 - 将第三方样式打到包中

    博客地址:http://blog.csdn.net/FoxDave 有许多第三方库可以帮助我们构建丰富的SharePoint Framework客户端web部件.并且这些JavaScript脚本常常包 ...

  3. SharePoint Framework 在web部件中使用已存在的JavaScript库 - 捆绑打包和外部引用

    博客地址:http://blog.csdn.net/FoxDave 在构建SPFx客户端web部件时,你可以使用公网已有的JavaScript库来构建强大的解决方案.但是在使用的时候你需要考虑你引用的 ...

  4. SharePoint Framework 把你的客户端web部件连接到SharePoint

    博客地址:http://blog.csdn.net/FoxDave 把你的web部件连接到SharePoint来访问SharePoint中的功能和数据,为终端用户提供更完整的体验.本篇会基于之前构 ...

  5. SharePoint Framework 构建你的第一个web部件(一)

    博客地址:http://blog.csdn.net/FoxDave SharePoint客户端web部件是出现在SharePoint页面的控件,但却是在浏览器本地运行的.他们是SharePoint ...

  6. Sharepoint 2013内容查询Web部件自定义显示样式(实战)

    分享人:广州华软 星尘 一. 前言 在进行Sharepoint开发时,经常会遇到内容展示个性化需求的问题,当然如果通过自定义开发控件对于内容展示的需求基本都可以很好的解决,但自定义开发也有不好的地方, ...

  7. SharePoint Framework 在web部件中使用已存在的JavaScript库 - JavaScript库的格式

    博客地址:http://blog.csdn.net/FoxDave JavaScript库格式 不同的JavaScript库的编译和打包方式各不相同.一些是以模块的方式打包的,而另一些是以纯脚本运行在 ...

  8. SharePoint Framework 向web部件中添加外部库

    博客地址:http://blog.csdn.net/FoxDave 在进行开发的时候,你很可能会想要引用一些公开的JavaScript库到你的项目中,本文将会介绍如何打包和共享这些库. 打包脚本 默认 ...

  9. SharePoint每日小贴士Web部件

    SharePoint每日小贴士Web部件 项目描写叙述         此Web部件从指定SP自己定义列表或一个选定的 RSS源选择一个随机项目.并显示一张图片.标题和一个Tip.         适 ...

随机推荐

  1. J a v a 的“多重继承”

    接口只是比抽象类“更纯”的一种形式.它的用途并不止那些.由于接口根本没有具体的实施细节——也就是说,没有与存储空间与“接口”关联在一起——所以没有任何办法可以防止多个接口合并到一起.这一点是至关重要的 ...

  2. BridgePattern(桥接模式)

    /** * 桥接模式 * @author TMAC-J * 应用于多维度方案 * 用组合的形式代替继承 * 符合单一职责原则 * 一个类只有一个引起他变化的原因 * 增加程序灵活性 */ public ...

  3. 看图理解JWT如何用于单点登录

    单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...

  4. ABP创建数据库操作步骤

    1 ABP创建数据库操作步骤 1.1 SimpleTaskSystem.Web项目中的Web.config文件修改数据库配置. <add name="Default" pro ...

  5. 整理下.net分布式系统架构的思路

    最近看到有部分招聘信息,要求应聘者说一下分布式系统架构的思路.今天早晨正好有些时间,我也把我们实际在.net方面网站架构的演化路线整理一下,只是我自己的一些想法,欢迎大家批评指正. 首先说明的是.ne ...

  6. css样式之超出隐藏

    文本超出部分隐藏,总结两种方法. 1.单行隐藏 html代码 <div class="mi">当文字超过范围的时候,超出部分会隐藏起来.</div> css ...

  7. 信息安全-1:python之playfair密码算法详解[原创]

    转发注明出处: http://www.cnblogs.com/0zcl/p/6105825.html 一.基本概念 古典密码是基于字符替换的密码.加密技术有:Caesar(恺撒)密码.Vigenere ...

  8. openresty 前端开发入门五之Mysql篇

    openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-my ...

  9. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  10. 我将系统从Windows迁移至Linux下的点点滴滴

    一.写在最前 由于本人的技术水平有限,难免会出现错误.本文对任何一个人有帮助都是我莫大的荣幸,任何一个大神对我的点拨,我都会感激不尽. 二.技术选型 在2013年8月低的时候,公司中了XXX市场监督局 ...