VS2005自带个人网站学习工具~研究 (1)

  • Post author:
  • Post category:其他




VS2005自带了一个所谓”个人网站初学者学习工具”(简称tool了~),实质上这是个个人网站的建站系统,而它虽然不大,却已经包含了绝大多数.net 2.0的新特性,masterpage theme DataSouce Membership等等….在现在看petshop程序还是一头雾水的水平下,学习这个显然是明智的选择 呵呵

新建一个”个人网站学习工具”网站,按要求运行,系统会初始化数据库,按照提示在ASP.NET网站配置里建一个administrator帐户,就可以开始玩了

首先看看网站大体结构:

主页->简历 链接 相册 这个是网站主要功能 其实最主要的就是一个相册!

另外提供一个 注册 和几个管理页面

管理页面都放在admin目录中


从web.config入手~


第一次接触这个,感觉一切都很新鲜(废话~),,先看看网站的配置文件吧

在教程里看到,系统里有一个web.config的模板,里面很详细,但是也很麻烦,头次看很难明白~

这个tool里面的就好懂得多,下面开始分析:

首先是connectionstring

定义了两个connectionstring 一个是Personal一个是LocalSqlServer

Personal里面定义的是网站需要存储的东西,主要是相册和photo

而LocalSqlServer,就是用.net自带的一些服务所需要的数据库~他这里默认是在App_Data下的一个文件,这个文件实质上也是一个数据库了,和上面没什么不同,只是对这个数据库的

(有时候不能运行和这个有关系)

很多操作都可以用现成的方法完成,比如成员服务 个性化信息服务等等,因为访问细节不需要来关心,因此连Provider都不用指定,,,初学情况下用默认的就行了

还有一句<remove name=”LocalSqlServer”/>,这个是用来覆盖掉继承的来自上一级的LocalSqlServer的~上一级的定义在服务器上会有,是给没有web.config的网站用的默认配置

,在win目录下

<pages styleSheetTheme=”White”/> 因此网站的默认theme就是White了,主题里包括default.css 系统会自动应用,因此不用每一页链接default.css

<customErrors mode=”RemoteOnly”/> 这一句是定义出错显示的东西,顾名思义就是用服务器的出错信息

mode可以改为off 或者 on 自定义出错页面 参考这个用法

<customErrors defaultRedirect=”http://hostName/applicationName/errorStatus.htm” mode=”On”>

<error statusCode=”404″ redirect=”filenotfound.htm” />

</customErrors>

<compilation debug=”true”/> 可以调试~第一次调试运行弹出的对话框就是说的这个了

然后定义身份验证是forms 基于窗体 具体的先不谈(下面都这样,具体的都先不谈)/

<globalization一句 定义编码~

然后打开Role管理服务

打开Sitemaps服务,并且设置

然后还定义了一个path 叫admin,也就是admin文件存放的目录,并且指定Administrators role可以访问 其他都不行 也就是后台了

就这些了


开始分析每个文件前,先看看网站的前台架构


整个网站都基于了default.master,这个master定义了页头和页角,用了sitemap,实际上所有的导航都是基于sitemap的,因此可以方便的扩展~用了两个menu和一个SiteMapPath,

样式控制都用css~

对了插一句,整个网站全部基于div+css~~~控制,而且也没有盲目使用,该用表格也用了表格(文章列表什么的),这样很不错

首页提供了登陆和每日照片

简历和链接比较基本,没有用到什么技术,就是两个普通页面~

照片提供了一个相册功能,albums.aspx列出了所有相册,通过Handler.ashx?AlbumID=1&Size=M访问相册~这里用了HTTPHandle实际上是photos.aspx?alumniid=**

然后photos.aspx根据alumniid列出照片,点击在通过http://localhost:7301/WebSite2/Handler.ashx?PhotoID=1&Size=S访问(和上面一样 实质上是

http://localhost:7301/WebSite2/Details.aspx?AlbumID=1&Page=1)

注意一下,这里通过HTTPHandle提供了类似一个照片缩略图的功能

还有一块儿就是管理功能,这里提供了创建相册,上传图片等等


不深入了 先开始default.aspx

右边都是静态页面,没什么可研究的,看左边

上面是一块LoginArea,是一个LoginView控件

定义了两个模板,<AnonymousTemplate> 和 <LoggedInTemplate> 很好理解

(涉及MemberShip的东西,暂时先不写 做个标记…………..)

左边的下面一块FormView

只用了一个ItemTemplate 实际上显示数据用的

绑定到ObjectDataSoure

绑定了几个值,

照片链接为 Details.aspx?AlbumID=<%# Eval(“AlbumID”) %>&Page=<%# Container.DataItemIndex %>

照片的src为 Handler.ashx?PhotoID=<%# Eval(“PhotoID”) %>&Size=M

照片编号为 <%# Eval(“PhotoID”) %>

先看看ObjectDataSource里的东西

业务逻辑类是PhotoManage 只用了一个GetPhotos方法为SelectMethod

去找到这个GetPhotos (有好几个,这里当然是没有参数的那一个)

GetPhotos的代码,先随机得到一个AlblumID,然后调用哪个需要传入AlbumID的GetPhotos

GetPhotos函数: 这个直接用了ado.net访问Personal数据库,它返回一个List<Photo>,,其实就是一个很多个Photo类组成的集合

也就是,GetPhotos 就是返回这个album里面所有的photo 放在一个集合里面,看看它是怎么工作的

通过SqlCommand调用了 GetPhotos 存储过程,传入的参数有@AlbumID和@IsPublic

@AlbumID是传入的,@IsPublic传入一个bool值,这个值通过当前用户是否在friends或者administrators组得到,在admin组或者在friends组就是false (这个@IsPublic意思是”访问

者是public”)

通过DataReader读出,然后写进List<Photo> 三个字段(其实是Photo类的属性),PhotoID,AlbumID,和Caption

最后返回list

这里要看一下GetPhotos存储过程要完成些什么

选出Photos,Photo的AlbumID为传入参数,同时此Photo对应Album的IsPublic为1或者对应Album的IsPublic与传入相同(即要么图片公开,要么图片不公开但是传入的参数是false,

也就是在admin或者friends组)

SELECT *

FROM [Photos] LEFT JOIN [Albums]

ON [Albums].[AlbumID] = [Photos].[AlbumID]

WHERE [Photos].[AlbumID] = @AlbumID

AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)

返回的应该是n条数 每条数据包含一条图片信息~包括binary

回到GetPhotos函数,List<Photo>包含3个字段,PhotoID AlbumID Caption

顺便再看一下Photo类,这个是所谓的”业务实体”

这个在photo.cs里 相当简单,给了三个属性,就是上面那三个,并不包含图像的二进制数据,只是存储了几个ID和描述

还漏了一个,随机得到一个AlblumID用的函数GetRandomAlbumID()

选出非空的album 加入list,随机一个最大为list.count的数,取AlbumID~SQL存储过程里还是有一不少技巧的~


这部分的绑定差不多就这样了~


下面解决两个问题,注意到,img的src指向那个文件,和Page指向的那个<%# Container.DataItemIndex %>


1 <%# Container.DataItemIndex %>




Container 顾名思义这里表示FormView DataItemIndex表示FormView的数据项,也就是表示第几项数据,绑定的时候,是绑定在一个List<Photo>上的,里面包含若干条photo数据,






具体显示哪一项是随机的




注意到FormView属性里 ondatabound=”Randomize” Randomize方法代码里随机指定了FromView的PageIndex,当前的页自然就能通过DataItemIndex得到~


2 关于Handler.ashx?PhotoID=<%# Eval(“PhotoID”) %>&Size=M




这个东西实现的是传入PhotoID和Size 就返回一个图片,类似直接输入jpg的url一样~理解起来似乎要麻烦一点(不过很有用,特别是到ajax~)




有个东西里面介绍这个,http://msdn.microsoft.com/msdnmag/issues/02/09/HTTPPipelines/




这个比较复杂,慢慢来 详细看看这个东西




要理解这个,首先需要了解一些HTTP Pipelines的东西,一个HTTP请求发出,会有一段Httpcontext,细节不关心,这个请求中间会经过一个HTTP Handlers的环节,这个环节会对请求的






文件进行处理,比如标准的HTTP Handler中有一条,对于扩展名为.aspx的文件,会调用System.Web.UI.PageHandlerFactory来处理,也就是把其当成一个页面,对于.asmx文件,会调用






WebService的Factory来处理,所以服务器认识这些文件(默认设置在本机machine.config和web.config中 win目录下那两个)




关注的是对于.ashx文件,它会调用System.Web.UI.SimpleHandlerFactory




这个Factory没有任何实现,当然就等我们去实现了~




还是先不关心细节,实现的方法就是在.ashx文件里加入<%@ WebHandler Language=”C#” Class=”Handler” %> 然后实现一个接口IHttpHandler




里面只有两个成员IsReusable和ProcessRequest




MSDN里还看到一种,在任意文件中实现IHttpHandler接口,然后在Web.config里面加入单独声明




<httpHandlers>




<add verb=”*” path=”handler.aspx” type=”HandlerExample.MyHttpHandler,HandlerTest”/>




</httpHandlers>




实际上是把handler.aspx的handler定位到HandlerTest.dll文件的HandlerExample.MyHttpHandler上,只要运行handler.aspx就会被Handle




而用.ashx做法应该是这样 默认.ashx文件是定位到SimpleHandlerFactory,这个类没有实现但是可继承,加入<%@ WebHandler Language=”C#” Class=”Handler” %>就继承了






这个类到本文件下面的Handler类…然后实现Handler类即可,因此访问此.ashx文件就会用本文件的Handler类来处理,不会影响其他的.ashx文件




IsReusable是一个只读属性,返回true就行,否则其他实例无法调用(实际上这里其他实例不可能调用得到,因为继承和实现都在一个地方




ProcessRequest()方法就是主要的实现了,由一个HTTPContent参数,当然表示当前的HttpContent了




看程序:




设置Content 因为需要把传入的Content变成一个图片,所以做一些处理




然后获取传入的数据,先得到size值,然后得到PhotoID,不存在就用AlbumID,不论如何用PhotoManager里的GetPhoto或者GetFirstPhoto获取照片的二进制数据,放在一个stream






里,确保stream里有数据后,写如HttpContent 这段代码:




// 将图像流写入响应流中




const int buffersize = 1024 * 16;




byte[] buffer = new byte[buffersize];




int count = stream.Read(buffer, 0, buffersize);




while (count > 0) {





context.Response.OutputStream.Write(buffer, 0, count);




count = stream.Read(buffer, 0, buffersize);




}




这样context被改变了,于是返回的时候就会返回stream,前面设置过类型是 image/jpeg 于是就相当于jpg文件了~




加一个 得注意context.Response属性的设置,具体的还得再研究~






还差一个,再去看看GetPhoto和GetFirstPhoto做了些什么(其实就是根据参数返回数据库中的binary)




GetPhoto 如果没有传入PhotoID,也就是HttpContent中没有传入PhotoID,直接按照Size返回现成的jpg,实质就3句话




string path = HttpContext.Current.Server.MapPath(“~/Images/”);




path += “placeholder-600.jpg”;




return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);




如果传入了PhotoID,就运行”GetPhoto”存储过程,返回的代码在这里~图片大小居然写在存储过程里了,传一个参数就行




object result = command.ExecuteScalar();




try {





return new MemoryStream((byte[])result);




} catch {





return null;




}




再看看存储过程,其实很简单,存储图片的时候就分别存储了4中不同size的图片,选的时候用就行了~所以说存储过程可以做不少事情……..






然后GetFirstPhoto 这个是从album中获取图片,其实差不多,存储过程不一样 本来是where photoid=@photoid现在成了albumid=@albumid 然后加个top 1








这就是数据库读取图片的实现~~~~~~

到这里default.aspx研究的差不多了,在研究到admin之前后面工作会轻松一些

注:PhotoManager.cs的内容穿插其中了,没有分开写



版权声明:本文为yayx原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。