韦恩卑鄙的神秘工坊

这里记录了工作中乐趣

2006年12月18日 #

建立一个使用.Net 2.0 MemberShip功能的标准例程(三)——绑定访问篇

     摘要: 经过上一章的例子 我们已经建立了一个标准的,有很多有趣(甚至有些是专业级)功能的登陆系统了。可是我们如何管理这个系统呢?难道我们要用m$提供的asp.net管理工具管理一辈子么?——当然不!那太可怕了!T_T——我们要自己写一个后台,一个可以根据用户权限自己修改的后台!@_@当然有一种数据库狂人,他们只冷冷的瞥了几眼m$提供的数据库结构,轻描淡写的破译了其中所有的奥妙之处,随手拖了5-6个grid... 阅读全文

posted @ 2006-12-18 14:46 韦恩卑鄙 阅读(4601) | 评论 (21)编辑

2006年12月13日 #

建立一个使用.Net 2.0 MemberShip功能的标准例程(二)——配置篇


从.net 2.0开始  asp.net 就进入了一个倡导少写代码多配置的时期

“机器先进阿 我们只要把猪赶进去 对面就会从传送带里传出香肠来!”

下面就是启动机器并且赶猪的工作。


在赶猪以前,我们先来了解一下,Web.Security 的工作大概方式



当一个页面打开  系统会首先读取System.web  按照其中的配置段  在进程中建立相应的各种Provider的实例 。
之后的所有登陆控件在交互的时候会自动调用相应Provider实例的方法和属性。所以大部分工作是在配置中进行的

组件部分的对象  有很多同行建议自己写  免得过于依赖aspnetDB  具体可以参考幻想曲的文章 
但我们这个是标准例程,所以暂时以 m$的标准库为基础建立


具体配置如下

1 配置数据库
运行    \WINDOWS\Microsoft.NET\Framework\v2.0.50727  下的Aspnet_regsql.exe



随后 向导便在SQL Server中建立了对应的表。
这些表就是.Net 2.0 默认Provider对应的表,如果你在建立一个新项目 就没必要在自己写烦人的登陆了,这些表和它们所支持默认Provider的已经涵盖了很多高级功能,包括cookie的支持、跨网站跨进程的登陆、找回密码、邮箱认证等功能,当然我们也可以扩展它们。





相对的  我们还需要在web.config 建立这个数据连接字符串(<configuration >段中)

    <connectionStrings>
        
<add name="MemberShip_Connection" connectionString="Data Source=.;Initial Catalog=MemberShip_Demo;Persist Security Info=True;User ID=sa;Password=abcdefg" providerName="System.Data.SqlClient"/>
    </connectionStrings>

这样数据库的配置就已经完成了,我爱厨房怎么说来着?阴干待用。

2  配置验证类型

一个asp.net缺省的身份验证是windows nt 登陆。如果我们要自己来处理验证信息就要在 <configuration >下面的<system.web> 段加入节点通知系统。

        <authentication mode="Forms">
            
<forms loginUrl="~\Membership\authing\Login.aspx" timeout="30000">
            
</forms>
        
</authentication>

mode=forms 表示我不要用默认的windows NT 权限设置、而用我们配置的这种自定义的 面向网页界面的验证方式。
loginUrl  表示如果访问某页需要验证的话 跳转到哪一个(一般是有Login控件的)地址来进行登陆。登陆完毕,会直接跳回刚才的页面。

3  配置各种Provider
Provider对于Membership的感觉有点像 DataAdapter对于Dataset的感觉,都是可选择的配件,你配置了不同的Provider 就有不同的用户数据库可以访问
目前Provider 默认提供两种官方Provider:  SQL Provider  & ADSI  Provider  
前者通过SqlServer数据库保存  后者直接连结windows域的adsi服务

例如
<membership defaultProvider="Main_SqlMemberShipProvider" userIsOnlineTimeWindow="20">
            
<providers>
                
<add connectionStringName="MemberShip_Connection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" passwordFormat="Hashed" applicationName="DEMO_Membership" name="Main_SqlMemberShipProvider" type="System.Web.Security.SqlMembershipProvider"/>
        
            
</providers>
        
</membership>

这个例子表示  我要用MemberShip_Connection这个连接字符串连接数据库(我们阴干待用的部分) 
用户不能找回密码但是可以重新设置密码,找回的时候需要密码提示问题,储存在数据库中的密码用sha1进行加密  等等细节问题。  对于公用的Membership数据库 区别名为  DEMO_Membership  .
Type是重要的选项 这决定你使用哪一个符合接口的具体的类型来担任Provider 项  如果你使用自己的Provider  可以把DLL作为引用添加在bin目录后  在这里填写详细的命名空间信息  比如“"System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089” 之类的东西  这里不作赘述

这时候 我们已经可以通过控件进行申请和登陆了   你所需要做的只是把控件拖到指定的页面上 然后test   也可以通过网站菜单下的管理工具进行修改





有些选项可能进不去 但是用户的删除和修改都可以尝试使用了。  我们只需要进一步配置 更多的功能就向我们敞开大门了~~~

同样我们配置Roles 和 Profile 的Provider
        <roleManager enabled="true" cacheRolesInCookie="true" cookieName=".ASPROLES" cookieRequireSSL="true" defaultProvider="SqlRoleProvider">
            
<providers>
                
<add connectionStringName="MemberShip_Connection" applicationName="DEMO_Membership" name="SqlRoleProvider" type="System.Web.Security.SqlRoleProvider"/>
            
</providers>
        
</roleManager>


<profile enabled="true" defaultProvider="SqlProfileProvider">
            
<providers>
                
<add name="SqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="MemberShip_Connection" applicationName="DEMO_Membership" description="SqlProfileProvider for SampleApplication"/>
            
</providers>
            
<properties>
            
        
<add name="UserAge" type="System.String" defaultValue ="21"></add>
        
<add name="UserSex" type="System.String" defaultValue ="Male"></add>
               
</properties>
        </profile>


经过编译以后  你已经可以轻松的在你的页面里面访问和设置你现在登陆的用户的各种信息:

   Protected Sub Button1_Click(ByVal sender As ObjectByVal e As System.EventArgs) Handles Button1.Click
        
Dim x As String = String.Empty
        x 
= x & Membership.GetUser().UserName & ":"
        x 
= x & Roles.GetRolesForUser(Membership.GetUser().UserName).Length & "个角色:"
        x 
= x & "年龄" & Profile.UserAge
        Button1.Text 
= x

    
End Sub

假如你没有登陆  可能会得到一个对象引用错误   但是你作为一个已知用户登陆的话   运行结果大概是这样



而刚才提到的网站管理工具  已经基本可以正常工作了。


配置篇的例子到此完成    至于每一个参数什么意义   MSDN上还是很全的。 如果查资料比较不方便  可以留言  我们一起讨论

下一章我们将使用ODS绑定这些数据到GridView 和FormView 上进行管理。

posted @ 2006-12-13 14:16 韦恩卑鄙 阅读(4914) | 评论 (14)编辑

建立一个使用.Net 2.0 MemberShip功能的标准例程(一)引子+预告 —— 这回不挖大坑了 保证填满

自从上一次更新blog到现在已经过了8个月了,某个信息采集小项目也被取消了  所以这里把大坑删除先。

但是上次的项目让我注意到,原本预定在信息采集项目中应用的 .net Membership功能是相当丰富的。通过简单的内建对象和配置工具 我们可以清晰方便的为我们的多个小项目建立非常易于扩展的用户管理功能。实际我做过的很多OA MIS 系统都是用户权限管理模块最浪费时间,有了这套系统,我还真有点高枕无忧了。

如果看到这里  你对Membership还没有什么明确的概念,请打开你的 VS2k5  看看一个网站工程的工具栏


“这不是那些莫名其妙的不能使用的登陆控件么”
没错,如果你没有用过Membership功能  这些控件所提供的事件、属性、方法 几乎是完全不可用的,果然是莫名其妙。

其实它们很好用,它们是一整套M$提供的登陆方案的基本面子成员。所谓侯门深似海,你看他们这几个控件并不起眼,但是你想象不到后面的封装有多麻烦,而我们用起来有多简单哦 @_@

先画一个简单的结构图


如图所示 其实我们把这个系统叫做MemberShip,只是因为这个系统最基本的组成部分,管理用户的基本类叫做MemberShip,整个的登陆方案其实是 System.Web.Security整个命名空间来支持的,其实叫做.net 2.0 Web安全方案才对。当然习惯上已经约定俗成了(我们这些菜鸟容易被表面疑惑,所以自己先约定了- -b)

下面的章节 我将从如何配置Membership开始  一直连载到自定义ObjectDataSource 管理 Membership \Roles \Profile
 敬请期待


posted @ 2006-12-13 10:56 韦恩卑鄙 阅读(4637) | 评论 (9)编辑

我回来了

个人原因(沉迷wow) 工作原因(工作性质从研发变成枯燥的维护)   到这这里荒废了许久  最近终于可以轻松的高研发  写心得上来了

posted @ 2006-12-13 10:08 韦恩卑鄙 阅读(151) | 评论 (0)编辑

2006年1月17日 #

关于asp2.0数据绑定的抱怨,大家跟着一起贴

考虑了一下 似乎有必要把这个发到首页 让大家都来发泄下

我的抱怨:

1 为什么IDE放弃了原有的DataSet数据绑定支持? 这样大量的老工程不能在2005IDE下正常编辑 
    ——以前的工程要升级是一个很艰巨工作 ,可是这样放弃Dataset绑定等于逼我们升级,还谈什么平滑过渡

2  Treeview控件绑定太愚蠢了  一个SiteMap真的有必要专门开发个控件么?看看dev expess 人家那个指定fatherkey 和nodekey的绑定树才叫绑定树呢~  

3 ObjectDataSource 指定的方法  如果方法是静态的则执行  不是静态的就创建一个实例   这个限制把整个ODS烹了一块鸡肋
在application的缓存 已经得到的dataset  / 内存里的xml数据  全都没办法用了  webservice的session cookie上下文也都白弄了 还要ObjectDataSource做什么? 


以上的抱怨也许是我还没有真正掌握这些绑定?  大家或者帮我解答下疑难  或者分享下解决建议 或者干脆和我一起抱怨吧!


posted @ 2006-01-17 12:09 韦恩卑鄙 阅读(2356) | 评论 (16)编辑

目前发现的VS2005 asp.net 数据绑定bug (二) -关于ObjectDatasource 和TableAdapter

(以下内容使用vs2005 teamsuit 英文版本)
自从dataset内部可以内建TableaDapter以后 ,貌似所有人的数据访问类都可以自动过期了
无论你是要login,count(*) , groupby 还是select into  你所要做的只是在相应的数据表的TableAdapter下面Add Query

更可恶的是^_^,貌似这是M$推荐的的 ObjectDataSource的绑定对象——IDE直接生成的唯一的(或者说唯一被我发现的)数据对象。

Well,如果是你推荐的  我自然要学习学习了。让我们来看看M$给我们提供了什么…………

——————————我是分隔线————————————

打开vs2005IDE   New->Website
http://localhost/ObjectDatasourceSite/

点击解决方案管理器 right click website -〉add new item ->dataset->Dataset1.xsd

忽略所有的向导  然后从服务器资源管理器拖拽一个数据表(northwind的Emoloyees看起来不错) ,放到已经打开的Dataset1.xsd里面

ok 我们有了一个装满字母的小房子  ,而且我们的数据访问对象作为地基已经在那里准备好fill something了



按照m$一贯的作风 我们来建立简单的数据绑定访问应用吧
dblclick default.aspx

扔一个GridView到这张新打开的纯洁的画布上
datasourceid->new datasource    -->objectdatasource
继续 objectdatasource向导  指定employoeesTableAdapter为我们的业务类
接着连续next   ,标准的M$操作不是么?

然后回到gridview ,right click  ->show Smart Tag     把里面的增删改对号都打开



看起来我们有了一个不错的M$风格的数据绑定,应该可以正常工作了>_<。

然后我们打开“正常工作”的页面   Edit   
然后Update


哈哈 熟悉的黄色屏幕出现了~


 

Server Error in '/ObjectDatasourceSite' Application.

ObjectDataSource 'ObjectDataSource1' could not find a non-generic method 'Update' that has parameters: LastName, FirstName, Title, TitleOfCourtesy, BirthDate, HireDate, Address, City, Region, PostalCode, Country, HomePhone, Extension, Photo, Notes, ReportsTo, PhotoPath, original_EmployeeID, Original_LastName, Original_FirstName, Original_Title, Original_TitleOfCourtesy, Original_BirthDate, Original_HireDate, Original_Address, Original_City, Original_Region, Original_PostalCode, Original_Country, Original_HomePhone, Original_Extension, Original_ReportsTo, Original_PhotoPath.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: ObjectDataSource 'ObjectDataSource1' could not find a non-generic method 'Update' that has parameters: LastName, FirstName, Title, TitleOfCourtesy, BirthDate, HireDate, Address, City, Region, PostalCode, Country, HomePhone, Extension, Photo, Notes, ReportsTo, PhotoPath, original_EmployeeID, Original_LastName, Original_FirstName, Original_Title, Original_TitleOfCourtesy, Original_BirthDate, Original_HireDate, Original_Address, Original_City, Original_Region, Original_PostalCode, Original_Country, Original_HomePhone, Original_Extension, Original_ReportsTo, Original_PhotoPath.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

xxxxx....
Version Information:
 Microsoft .NET Framework Version:2.0.50727.42; ASP.NET Version:2.0.50727.42



并不是我的设置缺少了什么  根据错误提示 是Gridview 生成的参数与 Tableadpter的参数不符合。 这绝对是bug

解决问题的步骤

1 把ObjectDataSource Update的参数  最后一个 keyfield  (这个表是EmployeeID)删除
2 把GridView 的datakeyName 删除
3 把GridView 的keyfield列设置成可读可写 
4 reconfig TableAdapter  在高级选项把并发读写那个对号去掉
(后3步是规避这个bug的另外一种表现,生成全null的original_{0}参数)


这样你将得到一个愚蠢的需要更新keyfield的绑定表(用模板列可以规避这个问题,那是后话)而且没有并发检查的能力
目前这是我能让gridview\ObjectDataSource和TableAdapter协同工作的唯一办法
希望大家能给我指出条更好的途径

posted @ 2006-01-17 10:01 韦恩卑鄙 阅读(2549) | 评论 (15)编辑

2006年1月12日 #

目前发现的 asp.net数据绑定的几个BUG(不定期连载)

(一) 绑定
首先值得一说的就是 SqlDataAdapter
在2005 team suit 的 ide中
当你从服务器资源管理器把一个数据表扔到窗体里  你的动作是ok的
绑定正常 显示正常 更新删除正常

这时候你心里犯了嘀咕  要是别人也在用这个个页面 产生了并发脏数据该怎么办?

于是你config sqldatasource ,在advance 里面  你打开了 use optimistic concurry
恭喜你  你的update +delete 全部作废了

原因:  貌似gv更新的时候 不能把更改前的数据表值 正确的传达给sqldatasource
(用sql server事件探看器跟踪发现Update和Delete命令的 @Original_XXX 参数全部为null 

似乎是gridview的bug  因为网上其他人说 datalist和formview没有这个毛病

(二)SqlDataSource生成的代码
 bug很简单 不能智能识别长字段
不管是text 还是ntext  在生成的代码里只有一个判断运算符  "="   连like 都不会用?



下期预告:著名的 ObjectDataSouce Bug 
ObjectDataSource: could not find a non-generic method '...'




posted @ 2006-01-12 18:33 韦恩卑鄙 阅读(5491) | 评论 (15)编辑

Dataset+TableAdapter _.net最终数据访问类出现? 我的心血显然被藐视了

     摘要: 随着不断深入了解 2005 team suit 的IDE我发现我错怪了M$ m$正在以一种极端激进的方式改变我们的数据访问模式在.net 1.1框架下编写自己的数据访问类时 我曾经抱怨过 如果M$的dataset 能够像组件一样 可以把各种各样的 DataAdepter捆绑进去该多好啊 这样数据储存器和数据I/O就可以一起发布了 编写也方便,何苦要建立DataAccess工程阿现在的Dataset... 阅读全文

posted @ 2006-01-12 18:07 韦恩卑鄙 阅读(5556) | 评论 (5)编辑

2006年1月9日 #

关于aspnet 2.0

终于还是升级了
看着自己的工程一下子变了模样  发现自己的开发习惯也不得不大幅度的修改
已经建立好的 组件-〉数据集 绑定开发方式也要彻底淘汰了
心里有点怕怕的

posted @ 2006-01-09 11:06 韦恩卑鄙 阅读(235) | 评论 (0)编辑

2005年11月24日 #

一个打乱顺序用的类

从今天开始 我会把自己以前工程中很好用的类  函数一点一点发上来 
一方面是对以前工作的纪念  一方面是让大家一起分享经验  最重要的 是逼迫自己学习新的知识不要抱着经验停滞不前。

用法简单  建立新实例后 
add增加参与的项    
toArray取出乱序数组 
RebuildOrder   重新排序


    
Class RandomListItem




    
Public Class Factory

posted @ 2005-11-24 15:42 韦恩卑鄙 阅读(310) | 评论 (4)编辑