ASP.NET:就是喜欢Web Form,就是喜欢拖控件(二)

ASP.NET:就是喜欢Web Form,就是喜欢拖控件(一)
ASP.NET:就是喜欢Web Form,就是喜欢拖控件(二)
ASP.NET:就是喜欢Web Form,就是喜欢拖控件(三)
ASP.NET:就是喜欢Web Form,就是喜欢拖控件(四)
ASP.NET:就是喜欢Web Form,就是喜欢拖控件(五)

这一篇...... 拖了太久了 原来打算叫FormView使用技巧 后来觉得内容其实不全是FormView相关,就改成了现在这个名字。在这个ASP.NET MVC流行的时候算是一种反抗?

第一篇实在太基础,也没好意思发上首页,大家可以到此处看看:ASP.NET:就是喜欢Web Form,就是喜欢拖控件(一)

咱们言归正传,书接上回,上一篇演示了如何利用VS自动生成要提交的表单。这里我们来考虑一个比较复杂的情况,带上传图片的表单以及在WebForm中显示数据库里保存的图片。

回忆一下这个数据库表:

commodity 商品

id name company_id
1 包子 3
2 蒸饺 3
3 人才 1
4 MVP 1
5 Window 7 2

 

既然是商品,每种商品配张图片是再正常不过的事情了,对于类似的需求,很多人喜欢把图片存到一起,然后用一个GUID作为文件名,数据库里存图片文件的GUID。然而随之而来的增、删、改、查备份都变得异常困难,这也太麻烦了!有没有更好的方法呢?

其实大部分数据库都是有Image这个字段类型的,我们完全可以把图片存入数据库中。我们期望的表结构是这样的:

id name company_id image
1 包子 3 [bin]
2 蒸饺 3 [bin]
3 人才 1 [bin]
4 MVP 1 [bin]
5 Window 7 2 [bin]

建表截图:

image

我们按照上一篇的方法,从这个数据表建立一个FormView,并且将Default Mode 设置为Insert,结果如下图:

image

好了,我们自动生成了一个插入数据的表单,但是很遗憾,image字段生成了TextBox,指望用户把图片内容copy下来输入到文本框里显然是极其不现实的想法。我们希望通过上传的方式来提交图片,那么,我们来编辑Insert模板,改为使用上传控件。

这是TextBox的数据绑定方式,TextBox的Text被绑定到了image字段。

image

然而很遗憾,当我们放一个FileUpload在这里时,只出现了2个Bindable属性,即使选中Show all properties,也没有我们想要的属性。

image

无计可施了吗?当然不是!我们还可以直接改ASP.NET代码。找到相应的代码先:

image

然后把 FileBytes属性绑定到image字段就好了:

<asp:FileUpload ID="imageFileUpload" runat="server" FileBytes='<%# Bind("image") %>'/>

 

然后我们把程序运行起来看看,按照原计划插入一个新商品种类:包子。

image

点击运行,我们却得到一个错误:SQL变量类型与字段不匹配。

其实我们只要把数据源里面的image参数类型限制删掉就好了:

image

好了,做完之后,数据看起来可以正确插入了。

image

 

 

 

 

好了,我们现在已经成功地将图片存入了数据库,但是存的到底对不对还有待证实,况且把图片存起来容易,显示出来难。

我们尝试用一个GridView来显示我们的表格,然而自动生成的表格会忽略掉image字段,看来要想显示图片还是要自己想办法。

 

首先我们来分析,HTML中图片要以单独的URL形式存在,所以我们不可能在同一个页面上做什么手脚。我们的图片URL的内容,就是对应商品的image字段里的二进制值了。所以我们需要一个类似图片Service的页面。这里我们建立一个叫做CommodityImage.aspx的页面。

当然我们不能为表中每一行都建立一个页面,所以CommodityImage.aspx还应该能够处理post或者get来的参数,根据数据项的主键来查询数据表,我们只要把这个页面的response流替换成数据表中image字段的内容就好了。

那么这里需要用C#来查询数据库嘛?当然不!为了尽量偷懒,我们这里还有些小技巧:P

我们要把页面里面零零碎碎的HTMl和ASP.NET标签先全都去掉,只留下

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CommodityImage.aspx.cs" Inherits="WebForm.CommodityImage" %>

然后我们切换到设计视图,拖一个SqlDataSource上去!然后配置这个DataSource,注意我们要的是只是image字段,而且必须从post或者get来的参数(这里我们还是用post来的)来得到id,所以我们要加上查询条件:

image

点击where之后,配置方法如图:

image

配置好数据源之后,我们就可以在Page_load里面用下面代码来替换Response数据流:

Response.Clear();
Response.ContentType = "image/jpeg";
foreach (System.Data.DataRowView record in SqlDataSource1.Select(DataSourceSelectArguments.Empty))
{
    Response.BinaryWrite(record[0] as Byte[]);
}

这里我们把SqlDataSource写到ASP.NET标记中,让IDE替我们完成了大部分工作,所以只要用6行有效代码就可以显示图片了,可以在页面url后面跟个?id=1看看效果,就是我们刚才上传的图片。

好了有了这个图片页面,我们在GridView里面把它显示出来,首先我们给Grid添加一个模板列:

image

然后就可以编辑这个列的模板了,既然是显示图片,我们就拖一个image上去,现在我们要把这个image的url指向我们刚才写好的图片服务页面,而且要把id作为QueryString传过去。具体做法看图便知,无需多言:

image

 

最后效果如图,看起来不错吧:(图中上传的示例图片如果侵犯了您的权利,请与我联系,我将第一时间处理,嘿嘿)

image 

下一篇或者几篇的内容可能包括:

自动填写字段:提交时间、提交用户ID、自增的主键、从session中安全地取得信息

多表查询:如何把引用的外键变成一个下拉列表?

融合客户端技术:用CSS让页面变得美观 用客户端JavaScript增加交互 看起来简陋的页面和大小不一凌乱的图片会立刻不一样

 

PS.关于这个系列

其实虽然一直在拖拖拽拽,但我并不是真的只是想分享一些拖拖拽拽的技巧,除了作为小项目中偷懒的小招数,我希望读过这几篇随笔的您能够更多思考WebForm究竟是怎样的一种编程模型。其实大部分时候,我们的劳累并非来自业务逻辑的复杂,而是来自错误的设计。Web应用程序涉及SQL、ASP.NET标记、C#、HTML、CSS、JavaScript等各个层次不同用途的语言,把业务逻辑和功能写在哪个层次其实对工作量的影响非常巨大。

这个系列来源于以前帮朋友做过的一个小项目,是一个类似进销存的系统、还有统计管理等一些功能,而其中唯一的一处C#代码就是上面提到的5行C#,我希望能分享这段有趣的开发经历,让大家看到WebForm的一个不同的侧面。

posted @ 2009-12-12 02:15 winter-cn 阅读(...) 评论(...) 编辑 收藏