美祺's profileEden of HexagonPhotosBlogListsMore ![]() | Help |
|
December 23 圣诞即至,给自己几个点心方案:) 就要耶诞了,Kobe灵巧的双手又要开始征服新的点心制作了,HoHo, Who am I:) 下午要去打球了,不过还没有想好晚上做什么好吃的点心给我的被试们(老马老巴)。嘿嘿,先列举出来,待俺回来继续制作。
情人蛋塔:
原料:175克面皮、3汤匙糖、60克无糖黄油、25克猪油、2茶匙水。 巧克力面包:(这个老妈肯定不赞成,容易胖) 配料:150克黑巧克力、75克无盐黄油、210克炼乳、2茶匙桂皮粉、75克杏仁、75克饼干,压碎、50克无核杏脯,切碎 做法: 1.在一个大方金属盒中铺上一层食品用铝箔。 2.用刀切碎行人。 3.把巧克力、黄油、牛奶和桂皮粉放入一个厚底锅中。用文火加热3-4分钟,并用木勺搅拌,直至巧克力融化。最后再把混合物搅匀。 4.把杏仁、碎饼干和杏脯加入巧克力混合物中,继续用木勺搅拌,直至混合均匀。 5.把所用混合物倒入准备好的盒子中,放入冰箱冷冻室冷冻一小时,直至冻结成块状。 6.食用时,把巧克力面包切片即可。 好了,就这么两,晚上看心情做一个咯:)
December 21 PetShop4.0中的Membership, Profile, Roles 整合性运用Membership, Profile, Roles 这几个和用户关键的操作有时候可以直接通过Studio2005上的asp.net配置进行管理,但是其实也可以自己做一个自己的整合用户功能管理器,这两天晓晓的尝试了一下,觉得还不错:)
对于MemberShip可以做以下的尝试:
MembershipUserWrapper.cs:
using System;
using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.ComponentModel; /// <summary>
/// MembershipUserWrapper 的摘要说明 /// </summary> public class MembershipUserWrapper : MembershipUser { //[Serializable] [DataObjectField(true)]
public override string UserName { get { return base.UserName; } } public MembershipUserWrapper(MembershipUser mu)
: base(mu.ProviderName, mu.UserName, mu.ProviderUserKey, mu.Email, mu.PasswordQuestion, mu.Comment, mu.IsApproved, mu.IsLockedOut, mu.CreationDate, mu.LastLoginDate, mu.LastActivityDate, mu.LastPasswordChangedDate, mu.LastLockoutDate) { }
} MembershipUserODS.cs
using System;
using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.ComponentModel; using System.Collections.Generic; /// <summary>
/// MembershipUserODS 的摘要说明 /// </summary> [DataObject(true)] public class MembershipUserODS { public MembershipUserODS() { // // TODO: 在此处添加构造函数逻辑 // } [DataObjectMethod(DataObjectMethodType.Select, false)]
public List<MembershipUserWrapper> GetMembers(bool returnAllApprovedUsers, bool returnAllNotApprovedUsers, string usernameToFind) { List<MembershipUserWrapper> memberList = new List<MembershipUserWrapper>(); if (!String.IsNullOrEmpty(usernameToFind))
{ MembershipUser mu = Membership.GetUser(usernameToFind); if (mu != null) { MembershipUserWrapper md = new MembershipUserWrapper(mu); memberList.Add(md); } } else { MembershipUserCollection muc = Membership.GetAllUsers(); foreach (MembershipUser mu in muc) { if (returnAllApprovedUsers && mu.IsApproved || (returnAllNotApprovedUsers && mu.IsApproved)) { MembershipUserWrapper md = new MembershipUserWrapper(mu); memberList.Add(md); } } } return memberList;
} } 由此可以从ObjectDatasource里直接取得数据,然后帮定在gridview中。
页面如下:
MembershipWrapperView.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MembershipWrapperView.aspx.cs" Inherits="Manager_MembershipWrapperView" %>
<!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> </head> <body> <form id="form1" runat="server"> <div> <asp:CheckBox ID="CheckBox1" runat="server" Checked="True" /> <asp:CheckBox ID="CheckBox2" runat="server" Checked="True" /> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:Button ID="Button1" runat="server" Text="Button" /><br /> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="UserName" DataSourceID="ObjectDataSource1"> <Columns> <asp:BoundField DataField="ProviderName" HeaderText="ProviderName" ReadOnly="True" SortExpression="ProviderName" /> <asp:CheckBoxField DataField="IsOnline" HeaderText="IsOnline" ReadOnly="True" SortExpression="IsOnline" /> <asp:BoundField DataField="LastPasswordChangedDate" HeaderText="LastPasswordChangedDate" ReadOnly="True" SortExpression="LastPasswordChangedDate" /> <asp:BoundField DataField="PasswordQuestion" HeaderText="PasswordQuestion" ReadOnly="True" SortExpression="PasswordQuestion" /> <asp:CheckBoxField DataField="IsLockedOut" HeaderText="IsLockedOut" ReadOnly="True" SortExpression="IsLockedOut" /> <asp:BoundField DataField="Comment" HeaderText="Comment" SortExpression="Comment" /> <asp:BoundField DataField="UserName" HeaderText="UserName" ReadOnly="True" SortExpression="UserName" /> <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" /> <asp:BoundField DataField="CreationDate" HeaderText="CreationDate" ReadOnly="True" SortExpression="CreationDate" /> <asp:CheckBoxField DataField="IsApproved" HeaderText="IsApproved" SortExpression="IsApproved" /> <asp:BoundField DataField="LastLockoutDate" HeaderText="LastLockoutDate" ReadOnly="True" SortExpression="LastLockoutDate" /> <asp:BoundField DataField="LastLoginDate" HeaderText="LastLoginDate" SortExpression="LastLoginDate" /> <asp:BoundField DataField="LastActivityDate" HeaderText="LastActivityDate" SortExpression="LastActivityDate" /> </Columns> </asp:GridView> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetMembers" TypeName="MembershipUserODS"> <SelectParameters> <asp:ControlParameter ControlID="CheckBox1" Name="returnAllApprovedUsers" PropertyName="Checked" Type="Boolean" /> <asp:ControlParameter ControlID="CheckBox2" Name="returnAllNotApprovedUsers" PropertyName="Checked" Type="Boolean" /> <asp:ControlParameter ControlID="TextBox1" Name="usernameToFind" PropertyName="Text" Type="String" /> </SelectParameters> </asp:ObjectDataSource> </div> </form> </body> </html> 关于具体的添加方法,可以自己依照老传统的Membership方式添加. 由此再列出Profile 和Roles的帮定代码:
ProfileEntry.cs
using System;
using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.ComponentModel; /// <summary>
/// ProfileEntry 的摘要说明 /// </summary> public class ProfileEntry { private string user_Name; private string firstName; private string lastName; [DataObjectField(true)]
public string UserName { get { return user_Name; } set { user_Name = value; } } public string FirstName
{ get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public ProfileEntry()
{ // // TODO: 在此处添加构造函数逻辑 // } } ProfileODS.cs
using System;
using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.ComponentModel; using System.Collections.Generic; using System.Web.Profile; /// <summary>
/// ProfileODS 的摘要说明 /// </summary> [DataObject(true)] public class ProfileODS { public ProfileODS() { // // TODO: 在此处添加构造函数逻辑 // } [DataObjectMethod(DataObjectMethodType.Select, false)]
public List<ProfileEntry> GetUserProfile(string userName, string propertyNames) { //bool doFilter = false; //string[] pNames = null; //if (!String.IsNullOrEmpty(propertyNames))
//{ // pNames = propertyNames.Split(new char[]{'|'}); // doFilter = true; //} List<ProfileEntry> pelist = new List<ProfileEntry>();
ProfileBase pf = ProfileBase.Create(userName); ProfileEntry pe = new ProfileEntry();
pe.UserName = pf.UserName; try
{ pe.FirstName = (String)pf.GetPropertyValue("FirstName"); pe.LastName = (String)pf.GetPropertyValue("LastName"); } catch (Exception ex) { return null; } pelist.Add(pe);
return pelist;
//foreach (SettingsPropertyValue itm in pf.PropertyValues)
//{ // if (!itm.Name.Equals("FirstName")) // { // bool doAdd = false; // if (!doFilter) // { // doAdd = true; // } // else if (Array.IndexOf(pNames, itm.Name) != -1) // { // doAdd = true; // } // if (doAdd)
// { // ProfileEntry pe = new ProfileEntry(); // pe.UserName = userName; // pe. // } // } //} } } RoleData.cs
using System;
using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.ComponentModel; /// <summary>
/// RoleData 的摘要说明 /// </summary> public class RoleData { private int number_OfUsersInRole; private string role_Name;
private string user_Name;
private bool user_InRole;
public bool UserInRole
{ get { return user_InRole; } set { user_InRole = value; } } [DataObjectField(true)]
public string UserName { get { return user_Name; } set { user_Name = value; } } public string RoleName
{ get { return role_Name; } set { role_Name = value; } } public int NumberOfUsersInRole
{ get { return number_OfUsersInRole; } set { number_OfUsersInRole = value; } } public RoleData()
{ // // TODO: 在此处添加构造函数逻辑 // } } RoleDataODS.cs
using System;
using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.ComponentModel; using System.Collections.Generic; /// <summary>
/// RoleDataODS 的摘要说明 /// </summary> [DataObject(true)] public class RoleDataODS { public RoleDataODS() { // // TODO: 在此处添加构造函数逻辑 // } [DataObjectMethod(DataObjectMethodType.Select,false)]
public List<RoleData> GetRoles(string userName, bool showOnlyAssignedRolls) { List<RoleData> roleList = new List<RoleData>(); string[] roleListStr = Roles.GetAllRoles(); foreach (string roleName in roleListStr) { bool userInRole = false; if (!String.IsNullOrEmpty(userName)) { userInRole = Roles.IsUserInRole(userName, roleName); } if (!showOnlyAssignedRolls || userInRole)
{ string[] usersInRole = Roles.GetUsersInRole(roleName); RoleData rd = new RoleData(); rd.RoleName = roleName; rd.UserName = userName; rd.UserInRole = userInRole; rd.NumberOfUsersInRole = usersInRole.Length; roleList.Add(rd); } } return roleList;
} [DataObjectMethod(DataObjectMethodType.Select, false)]
public List<RoleData> GetRoles() { return GetRoles(null, false); } } web.config:
<?xml version="1.0"?>
<!-- 注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置。可以使用 Visual Studio 中的 “网站”->“Asp.Net 配置”选项。 设置和注释的完整列表在 machine.config.comments 中,该文件通常位于 \Windows\Microsoft.Net\Framework\v2.x\Config 中 --> <configuration > <appSettings/> <connectionStrings>
<add name="NorthwindConnectionString" connectionString="Data Source=MICROSOF-38E58D\VENUS;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=1" providerName="System.Data.SqlClient" /> <add name="PetShopCopyDataConnectionString" connectionString="Data Source=MICROSOF-38E58D;Initial Catalog=PetShopCopyData;Persist Security Info=True;User ID=sa;Password=1" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <!-- 设置 compilation debug="true" 将调试符号插入 已编译的页面中。但由于这会 影响性能,因此只在开发过程中将此值 设置为 true。 --> <compilation debug="true"/> <!-- 通过 <authentication> 节可以配置 ASP.NET 使用的 安全身份验证模式, 以标识传入的用户。 --> <authentication mode="Forms"> <forms loginUrl="Login.aspx" timeout="30000" /> </authentication> <authorization>
<deny users="?"/> </authorization> <anonymousIdentification enabled="true"/>
<profile defaultProvider="PetShopCopyDataProvider">
<providers> <add name="PetShopCopyDataProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="PetShopCopyDataConnectionString"/> </providers> <properties> <add name="FirstName" type="String" defaultValue="?" allowAnonymous="true"/> <add name="LastName" type="String" defaultValue="?" allowAnonymous="true"/> </properties> </profile> <!-- <profile >
<properties> <add name="FavoriteColor" defaultValue="Red" allowAnonymous="true"/> <add name="FirstName" type="String" defaultValue="?" allowAnonymous="true"/> <add name="LastName" type="String" defaultValue="?" allowAnonymous="true"/> <add name="PageVisits" type="Int32" allowAnonymous="true"/> <group name="Address"> <add name="Street" type="String" allowAnonymous="true" /> <add name="City" type="String" allowAnonymous="true" /> </group> <group name="Preferences"> <add name="ReceiveNewsletter" type="Boolean" defaultValue="false" allowAnonymous="true"/> </group> <add name="ShoppingCart" type="ShoppingCart" serializeAs="Binary" allowAnonymous="true"/> </properties> </profile> <profile inherits="UserInfo"></profile>--> <membership defaultProvider="Main_SqlMemberShipProvider" userIsOnlineTimeWindow="20"> <providers> <add connectionStringName="PetShopCopyDataConnectionString" minRequiredPasswordLength="1" passwordStrengthRegularExpression="" minRequiredNonalphanumericCharacters="0" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" passwordFormat="Hashed" name="Main_SqlMemberShipProvider" type="System.Web.Security.SqlMembershipProvider"/> </providers> </membership> <roleManager enabled="true" cacheRolesInCookie="true" cookieName=".ASPPROFILES" cookieRequireSSL="true" defaultProvider="SqlRoleProvider"> <providers> <add name="SqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="PetShopCopyDataConnectionString"/> </providers> </roleManager> <!-- 如果在执行请求的过程中出现未处理的错误, 则通过 <customErrors> 节可以配置相应的处理步骤。具体说来, 开发人员通过该节可以配置 要显示的 html 错误页 以代替错误堆栈跟踪。 <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" /> <error statusCode="404" redirect="FileNotFound.htm" /> </customErrors> --> <caching> <sqlCacheDependency enabled="true" pollTime="10000"> <databases> <add name="Categories" connectionStringName="PetShopCopyDataConnectionString" pollTime="10000"/> </databases> </sqlCacheDependency> </caching> </system.web> <location path="CreateUser.aspx"> <system.web> <authorization> <allow users="?"/> </authorization> </system.web> </location> </configuration> Ok, 如果看不懂,可以给我地址,我把Project发过来
December 20 角色访问控制(RBAC)角色访问控制(RBAC)
角色访问控制(RBAC)引入了Role的概念,目的是为了隔离User(即动作主体,Subject)
与Privilege(权限,表示对Resource的一个操作,即Operation+Resource)。 Role作为一个用户(User)与权限(Privilege)的代理层,解耦了权限和用户的关系,所 有的授权应该给予Role而不是直接给User或Group。Privilege是权限颗粒,由 Operation和Resource组成,表示对Resource的一个Operation。例如,对于新闻的删除 操作。Role-Privilege是many-to-many的关系,这就是权限的核心。 基于角色的访问控制方法(RBAC)的显著的两大特征是:1.由于角色/权限之间的变化
比角色/用户关系之间的变化相对要慢得多,减小了授权管理的复杂性,降低管理开 销。2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。 RBAC基本概念:
RBAC认为权限授权实际上是Who、What、How的问题。在RBAC模型中,who、what、how构
成了访问权限三元组,也就是“Who对What(Which)进行How的操作”。 Who:权限的拥用者或主体(如Principal、User、Group、Role、Actor等等)
What:权限针对的对象或资源(Resource、Class)。
How:具体的权限(Privilege,正向授权与负向授权)。
Operator:操作。表明对What的How操作。也就是Privilege+Resource
Role:角色,一定数量的权限的集合。权限分配的单位与载体,目的是隔离User与
Privilege的逻辑关系. Group:用户组,权限分配的单位与载体。权限不考虑分配给特定的用户而给组。组可
以包括组(以实现权限的继承),也可以包含用户,组内用户继承组的权限。User与 Group是多对多的关系。Group可以层次化,以满足不同层级权限控制的要求。 RBAC的关注点在于Role和User, Permission的关系。称为User assignment(UA)和
Permission assignment(PA).关系的左右两边都是Many-to-Many关系。就是user可以有 多个role,role可以包括多个user。 凡是用过RDBMS都知道,n:m 的关系需要一个中间表来保存两个表的关系。这UA和PA就
相当于中间表。事实上,整个RBAC都是基于关系模型。 Session在RBAC中是比较隐晦的一个元素。标准上说:每个Session是一个映射,一个用
户到多个role的映射。当一个用户激活他所有角色的一个子集的时候,建立一个 session。每个Session和单个的user关联,并且每个User可以关联到一或多个 Session. 在RBAC系统中,User实际上是在扮演角色(Role),可以用Actor来取代User,这个想法
来自于Business Modeling With UML一书Actor-Role模式。考虑到多人可以有相同权限 ,RBAC引入了Group的概念。Group同样也看作是Actor。而User的概念就具象到一个 人。 这里的Group和GBAC(Group-Based Access Control)中的Group(组)不同。GBAC多用
于操作系统中。其中的Group直接和权限相关联,实际上RBAC也借鉴了一些GBAC的概 念。 Group和User都和组织机构有关,但不是组织机构。二者在概念上是不同的。组织机构
是物理存在的公司结构的抽象模型,包括部门,人,职位等等,而权限模型是对抽象概 念描述。组织结构一般用Martin fowler的Party或责任模式来建模。 Party模式中的Person和User的关系,是每个Person可以对应到一个User,但可能不是
所有的User都有对应的Person。Party中的部门Department或组织Organization,都可 以对应到Group。反之Group未必对应一个实际的机构。例如,可以有副经理这个Group ,这是多人有相同职责。 引入Group这个概念,除了用来解决多人相同角色问题外,还用以解决组织机构的另一
种授权问题:例如,A部门的新闻我希望所有的A部门的人都能看。有了这样一个A部门 对应的Group,就可直接授权给这个Group。 Role作为一个用户(User)与权限(Privilege)的代理层,解耦了权限和用户的关系,所
有的授权应该给予Role而不是直接给User或Group。Privilege是权限颗粒,由 Operation和Resource组成,表示对Resource的一个Operation。例如,对于新闻的删除 操作。Role-Privilege是many-to-many的关系,这就是权限的核心。 基于角色的访问控制方法(RBAC)的显著的两大特征是:1.由于角色/权限之间的变化 比角色/用户关系之间的变化相对要慢得多,减小了授权管理的复杂性,降低管理开 销。2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。 December 12 PetShop4.0——使用SQLMemberShipProvider当在外网做验证或者内网有没有配置活动目录的时候我们可以使用SQLMembershipProvider来作为验证的数据源,其实默认的设置就是使用SQLMembershipProvider的 基本步骤 按照如下的步骤来为表单验证启用SqlMembershipProvider 1、配置表单认证 2、按照membership数据库 3、建立用户 4、认证用户 1、省略。。。同ActiveDirectoryMembershipProvider 2、按照membership数据库 在使用SqlMembershipProvider以前需要安装一个membership数据库,使用一个SQL SERVER管理员权限登录到服务器,然后在Visual Studio 2005命令行模式下执行下面的语句
aspnet_regsql.exe -E -S localhost -A m 看下几个参数: -E 表明此帐号使用windows集成认证 -S 表明需要安装数据库的服务器名 -A m 表明自动为membership建立相应的表和存储过程
注意:Aspnet_regsql 工具同样为其他ASP.NET 2.0特性安装数据库,比如说成员管理,Profile,个性化Web Parts还有Web Events等,当然都会有其他的命令,如果你不使用任何参数的话可以以想到模式运行程序,会允许你在安装的过程中指定数据库服务器和你需要安装的组件
3、配置SqlMembershipProvider Machine.config其实默认就是使用SQL Server Express作为SqlMembershipProvider的,如果你的数据库不是运行在本机的,可以修改下配置 <connectionStrings> <add name="MySqlConnection" connectionString="Data Source=MySqlServer;Initial Catalog=aspnetdb;Integrated Security=SSPI;" /> </connectionStrings> <system.web> ... <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15"> <providers> <clear /> <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MySqlConnection" applicationName="MyApplication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" passwordFormat="Hashed" /> </providers> </membership>
更多信息看本文“SqlProviderMembershipProvider属性配置”章节 Step 4. Create Users 4、建立用户: 省略。。。同ActiveDirectoryMembershipProvider 5、认证用户: 省略。。。同ActiveDirectoryMembershipProvider
ActiveDirectoryMembershipProvider的属性配置 表1显示了ActiveDirectoryMembershipProvider的属性,默认值和用途 表1: ActiveDirectoryMembershipProvider的属性配置 (这部分不翻译)
如果要启用取回密码你需要在<providers>后增加<add>设置attributeMapPasswordQuestion 和 attributeMapPasswordAnswer 属性来增加ActiveDirectoryMembershipProvider详细见How To: Use Forms Authentication with Active Directory in ASP.NET 2.0. SqlMembershipProvider Configuration Attributes SqlMembershipProvider属性配置 表2显示了SqlMembershipProvider的属性,默认值和用途 表 2. SqlMembershipProvider属性配置
表3列出了一些Membership类重要的一些方法参数和用法 表3. Membership 类方法
注意 GetAllUsers 方法在 RTM 版本的 .NET Framework 2.0 会取消
特别注意 默认情况下表单认证的票据传输是明文的,为了防止票据被盗窃,我们还是建议你为服务器启用SSL。设置requireSSL属性为true来启用SSL,下面的例子显示了怎么启用SSL,还有不管用户使用http还是https形式的url进入网站都能启用,你可以尝试登录到loginUrl指定的页面看看,但是需要保证这个页面是没有任何约束的 <configuration> <system.web> <authentication mode="Forms"> <forms loginUrl="https://myserver/mywebapp/secure/Login.aspx" protection="All" timeout="30" name="AppNameCookie" path="/FormsAuth" requireSSL="true" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseCookies" enableCrossAppRedirects="false"/> </authentication>
<!—禁止没有权限的用户 --> <authorization> <deny users="?" /> <allow users="*" /> </authorization> </system.web> </configuration>
<!—使得登录页面没有任何限制 --> <location path="secure"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> December 10 Excel的导出及其他文件的导出(二)接上一篇:
对于Excel的模版定制输出,我们可以再看看几个例子,有将Excel的一个sheet保存为html后对其中的模版输出,也可以将Excel文件保存为xml表的形式,然后在xml中进行操作,前者的缺点是不支持多sheet,后者的优点明显,可以多sheet,而且可以定制函数功能(考,微软真tmd的!!!无语)。
a:对与只要输出一个sheet的Excel模版,可以先将excel模版文件进行保存为网页(html),然后选择单个表保存,那么可以输出一个sheet的html页,这个就是我们用来作为模版的html.
剩下只要在具体定制的地方进行字符替换即可:)给出例子如下:
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = contentType; //HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"; //HttpContext.Current.Response.ContentType = "application/vnd.xml";//也可以 //HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//
//HttpContext.Current.Response.Charset = "GB2312"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");// HttpContext.Current.Response.Charset = "UTF8"; //HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode("ProjectExport", Encoding.UTF8) + ".xls"); HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(fileName, Encoding.UTF8) + fileType); StringBuilder strBuilder = new StringBuilder(); using (StreamReader reader = new StreamReader(Server.MapPath(@"~\ExcelExport\HtmlModel.htm"), Encoding.UTF8))
//所有的.net下编码都是支持UTF8的,所以最好用这个读取。 { while (reader.Peek() >= 0) { strBuilder.Append(reader.ReadLine()); } } StringWriter stringWriter = new StringWriter(htmltext);
HttpContext.Current.Response.Write(stringWriter.ToString()); stringWriter.Close();
b:如果输出多个sheet的情况就不一样了。同样,利用妖怪及的excel,先另存为xml表格,这样可以生成一个有固定格式的xml,如:
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> <Author>hwk</Author> <LastAuthor>微软用户</LastAuthor> <LastPrinted>2006-08-18T06:58:58Z</LastPrinted> <Created>2006-08-18T00:37:09Z</Created> <LastSaved>2006-12-04T07:16:02Z</LastSaved> <Version>11.5606</Version> </DocumentProperties> <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> <WindowHeight>10470</WindowHeight> <WindowWidth>15480</WindowWidth> <WindowTopX>0</WindowTopX> <WindowTopY>120</WindowTopY> <ActiveSheet>2</ActiveSheet> <ProtectStructure>False</ProtectStructure> <ProtectWindows>False</ProtectWindows> </ExcelWorkbook> <Styles> <Style ss:ID="Default" ss:Name="Normal"> <Alignment ss:Vertical="Bottom"/> <Borders/> <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/> <Interior/> <NumberFormat/> <Protection/> </Style> <Style ss:ID="m32074384"> <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/> <Borders> <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/> <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/> <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/> <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/> </Borders> <Font ss:FontName="宋体" x:CharSet="134" ss:Bold="1"/> <Interior ss:Color="#C0C0C0" ss:Pattern="Solid"/> </Style> ..... </Panes> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> </Workbook> 可以看到,通过xml可以分出若干个sheet,所以这个也可以利用上面的方式进行文件读取后字符替换。
通过这个方式,可以看到,excel的输出可以是十分灵活的方式,有的时候不一定非要直接输出exel文件,其他的流也能胜任这项工作。 December 04 Excel的导出及其他文件的导出(一)Excel的导出是最近一直在弄的,终于也结束了,留下点心得,大家一起分享下:)
导出基本上分2种: 1,基于字符流的输出,2,基于Excel本体的输出。
1。基于字符流的输出又可以有几种方式:
A:基于控件的输出,众所周知,几乎每个WebControl都继承了RenderControl(HtmlTextWriter htmlWrite),此方法得以以字符流 的形式输出具有html标签的控件形态,这个无疑方便了作为Excel导出。
列如:
ExcelPort1.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ExcelPort1.aspx.cs" Inherits="ExcelExport_ExcelPort1" %>
<!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> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> 通过控件导出<br /> <br /> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="CustomerID" DataSourceID="SqlDataSource1"> <Columns> <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True" SortExpression="CustomerID" /> <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" /> <asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" /> <asp:BoundField DataField="ContactTitle" HeaderText="ContactTitle" SortExpression="ContactTitle" /> <asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" /> <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" /> <asp:BoundField DataField="Region" HeaderText="Region" SortExpression="Region" /> <asp:BoundField DataField="PostalCode" HeaderText="PostalCode" SortExpression="PostalCode" /> <asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" /> <asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" /> <asp:BoundField DataField="Fax" HeaderText="Fax" SortExpression="Fax" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT * FROM [Customers]"></asp:SqlDataSource> </div> </form> </body> </html> ExcelPort1.aspx.cs
using System;
using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class ExcelExport_ExcelPort1 : System.Web.UI.Page
{ protected void Page_Load(object sender, EventArgs e) { }
protected void Button1_Click(object sender, EventArgs e) { Response.Clear(); Response.AddHeader("content-disposition", "attachment;filename=FileName.xls");
//Response.ContentType = "application/ms-excel";也可以 // 如果设置为 GetEncoding("GB2312"),导出的文件将会出现乱码。
//可用Response.ContentEncoding = System.Text.Encoding.UTF7;
Response.Charset = "";
// If you want the option to open the Excel file without saving than
// comment out the line below
// Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.xls";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
// turn off paging
GridView1.AllowPaging = false; GridView1.RenderControl(htmlWrite);//每个控件都有renderControl方法来输出html格式的字符流 Response.Write(stringWrite.ToString());
Response.End();
}
//这个方法是为了避免出现以下的错误: 类型“GridView”的控件“GridView1”必须放在具有 runat=server 的窗体标记内。
//通常组件的输出都缺少runat=server,所以会引起以上错误。 //还有另以个方式: //当用GridView导出Execl的时候,也会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示。 //有两种方法可以解决以上问题: //1.修改web.config(不推荐)<pages enableEventValidation ="false" ></pages> //2.直接在导出Execl的页面修改 //<%@ Page Language="C#" EnableEventValidation = "false" AutoEventWireup="true" // CodeFile="ExportGridView.aspx.cs" Inherits="ExportGridView" %>
public override void VerifyRenderingInServerForm(Control control) { // Confirms that an HtmlForm control is rendered for the specified ASP.NET server control at run time.
}
}
B:基于模版的输出。首先看一个例子,html模版定制输出: HtmlExport.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="HtmlExport.aspx.cs" Inherits="ExcelExport_HtmlExport" %>
<!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> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />html模版定制输出</div> </form> </body> </html> HtmlExport.aspx.cs
using System;
using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.IO; using System.Text; public partial class ExcelExport_HtmlExport : System.Web.UI.Page
{ protected void Page_Load(object sender, EventArgs e) { }
protected void Button1_Click(object sender, EventArgs e) { Response.Clear(); Response.AddHeader("content-disposition", "attachment;filename=FileName.html");//文件名还是英文巴,中文的话保存没有问题,但是打开就会因为编码问题而出错。
Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//
//Response.Charset = ""; Response.Charset = "GB2312";//显示的时候要以gb2312显示 // If you want the option to open the Excel file without saving than
// comment out the line below
// Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "text/html";//MIME Reference,参见:http://www.w3schools.com/media/media_mimeref.asp
//StreamReader reader = new StreamReader(Server.MapPath(@"~\ExcelExport\HtmlModel.htm"), Encoding.UTF8);//所有的.net下编码都是支持UTF8的,所以最好用这个读取。
StringBuilder strBuilder = new StringBuilder();
using (StreamReader reader = new StreamReader(Server.MapPath(@"~\ExcelExport\HtmlModel.htm"), Encoding.UTF8))
//所有的.net下编码都是支持UTF8的,所以最好用这个读取。 { while (reader.Peek() >= 0) { strBuilder.Append(reader.ReadLine()); } } strBuilder.Replace("$DateTime", DateTime.Now.ToShortTimeString());//模版内相应的字符进行替换
System.IO.StringWriter stringWrite = new System.IO.StringWriter(strBuilder);//参数为StringBuilder
Response.Write(stringWrite.ToString());
Response.End();
} } HtmlModel.htm
<!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> <title>无标题页</title> </head> <body> <form action=""> hello,你好 this is the model html page:)<br /> <br /> Now is : $DateTime </form> </body> </html> 由此可以看到,通过读取文件中的字符流并对其进行加工可以达到Excel输出的目的。关键的部分在于:Response.ContentType = "text/html"; 这里可以定义很多文件形式,由于我们憎恨的微软支持在其框架内跨结构读取文件,所以一个txt,html,xml,cvs等都可以在妖怪级的excel里读出来。虽然我们讨厌一手包办的奶妈式框架,但是不得不承认,要达到真正批评一个框架好坏的水平并非是现在的我们所能担当得,所以,还是那句老话:好好用人家的,别想自己发明文字:)
对于Excel的模版定制输出,我们可以再看看几个例子,有将Excel的一个sheet保存为html后对其中的模版输出,也可以将Excel文件保存为xml表的形式,然后在xml中进行操作,前者的缺点是不支持多sheet,后者的优点明显,可以多sheet,而且可以定制函数功能(考,微软真tmd的!!!无语)。
有点太晚了,明天下班回来继续写好了。 December 03 杜琪峰的又一力作《放·逐》——难得的男人应该看的片子 又到周末本来想先看下两个英语片的,不过最后还是选择了久闻大名的《放·逐》,不仅因为个中的导演是我所喜欢的,还有一些重量级的大腕出演其中,连一向看似不错的任贤齐也在重大派的面前显得稚嫩了一点。
故事还是依旧是围绕着兄弟,枪,黑道展开,同时也有着一份家人的迁靽。五个配合默契的杀手中有一人突然金盆洗手,并且带着妻子远离尘嚣,在澳门过着恬静的生活。 一天,当年的四个同伴先后出现在澳门,五人重新聚首百感交集。但是每个人心底里都有不同的盘算和目的,其中有人更是仇家派来杀人灭口的。与此同时,另外几名杀手也肩负使命出现在澳门,于是平静的小镇掀起了连场激斗。直到最后大家面对彼此紧扣扳机的时候,才弄清楚各自此行的真实目的,并且等待着命运的裁决。
患难与共,生死相允,男人间其实可以很简单。男人间又可以没有理由的去做同一件事。这只是第一次看,已经让我深深的被老杜所想表达的内容所震撼,第二次,第三次,也许,这部片子我会长久保留,长久的回味。
特此记录,以平内心澎湃。 December 02 javascript——页面跳转javascript——页面跳转,设定固定时间后跳转到指定页面
<%@ Page Language="C#" EnableViewState="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script type="text/javascript"> <!-- var duration=2900; var endTime = new Date().getTime() + duration + 100; function interval() { var n=(endTime-new Date().getTime())/1000; if(n<0) return; document.getElementById("timeout").innerHTML = n.toFixed(3); setTimeout(interval, 10); } window.onload=function() { setTimeout("window.location.href='http://community.csdn.net/index.htm'", duration); interval(); } //--> </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>发生错误</title> </head> <body> <form id="form1" runat="server"> <div> 对不起!你所访问的页面出错!<br /> 系统在 <span id="timeout">3.000</span> 秒后 将自动跳转到 <a href="http://community.csdn.net/index.htm">社区首页</a> </div> </form> </body> </html> 双皮奶的制作1 材料:牛奶(越浓越好,就不要考虑什么低脂、脱脂一类的啦)、鸡蛋、白 糖、蜜蜜豆(我是在'面爱面'买的现成儿的,¥7.5一大袋,超市里好像有其他种类的红豆 沙什么的,不怕麻烦自己煮当然也好)、淡奶油(我只知道雀巢出的那种小盒装,大概七八 块钱,这个是锦上添花,没有也没关系) 2 双皮奶的制作:(说实话,正点的双皮奶我一次也没做出来过,但是步骤照猫画虎的也学 了个大概)牛奶煮沸,倒进碗里,凉下来之后表面会结一层奶皮。小心挑开奶皮,把牛奶慢 慢倒入另一个碗里,奶皮留在原先的碗底。在牛奶里加少量白糖和鸡蛋清(通常250ml的小 袋牛奶我加一个蛋清,但不是很好凝固,so建议蛋清量再稍多一点),我也会放两匙淡奶油 进去,这样味道会更香一些吧,把这些材料搅拌均匀,倒回之前的碗里。够水平的话,原先 碗底的那层奶皮会浮起来。接着放进蒸锅,蒸到牛奶凝固就可以了。 3 奶油蜜蜜豆的制作:碗里倒些雀巢淡奶油(盒子上说明,倒出之前要充分摇匀)加白糖, 用力搅打,至少要三五分钟的时间,奶油才会呈现比较稠的状态,再和蜜蜜豆搅拌在一起。 4 把混合好的奶油蜜蜜豆放到蒸好的双皮奶上面,热吃凉吃都不错:) |
|
|