多文件批量上传

用一个页面实现文件上传,一般只需要使用HtmlInputFile的runat=server版本就行了,但是现在有些不同的地方:
1、直接上传到数据库的image类型的字段中,而不产生本地文件;
2、多个文件同时上传;
3、上传的文件组最后要同其他相关信息进行关联;

解决方法主要有两种:
1、每次上传一个文件到临时目录,返回并保存相关信息到ViewState,最后提交的时候,统一将文件写入数据库,并根据相关信息做关联;
2、每次上传一个文件到数据库,返回并保存相关信息到ViewState,最后提交的时候,根据相关信息做关联;
3、每次采集HtmlInputFile中的信息到ListBox,最后统一上传多个文件,并做相关关联;

无疑,第三种是其中最好的一种,但是上传多个文件却比较麻烦,本来想在提交的时候,分别多次设置 HtmlInputFile.PostedFile.FileName属性,再多次调用SaveAs进行上传,但在一次提交过程中它不允许重设 FileName属性(事后想想,确实应该不行:P)
后来又想在后台动态添加HtmlInputFile控件并且设其Visible属性为false,结果好像还是不行,因为还是不准自己指定那个怨念的FileName属性

结果:
增加文件按钮:
if( null == m_htmlInputFile )
m_htmlInputFile = new ArrayList();
m_htmlInputFile.Add( FileInputField );

其中FileInputField为System.Web.UI.HtmlControls.HtmlInputFile类型;
并且注意设置m_htmlInputFile这个ArrayList为static,以防每次增加文件后被刷新为null:(
这里其实就每次Add那个Html控件就行了,他们都对应相同的html控件,但是后台的对象每Add一次增加一个:)

提交按钮:
if( null == m_imageList )
m_imageList = new ArrayList();
if( null == m_imageTypeList )
m_imageTypeList = new ArrayList();
foreach( HtmlInputFile hif in m_htmlInputFile )
{
System.Drawing.Image image = System.Drawing.Image.FromStream( hif.PostedFile.InputStream );
m_imageList.Add( image );
m_imageTypeList.Add( hif.PostedFile.ContentType );
}

显示图片:
在GetImage.aspx?ImageID=*页面的Page_Load中
Response.ContentType = m_image.ImageType;
Response.BinaryWrite( m_image.Img );

注意采用BinaryWrite以及设置ContentType为image/pjpeg等

最后在保存文件到后端数据库的时候有点小不爽:
MemoryStream ms = new MemoryStream();
image.Save( ms, System.Drawing.Imaging.ImageFormat.Jpeg );//image是System.Drawing.Image
m_image = new byte[ms.Length];//m_image是byte[]
ms.Position = 0;
//If Too Long, ...
ms.Read( m_image, 0, Convert.ToInt32(ms.Length));

这里ms.Length是long类型,但是同一个类-MemoryStream的Read方法的第三个参数是int型,涉及到一个向下的类型转换,如果Length过大,应该这里会有问题,不知是怎么回事:(

发布Web Services

笔记本上Release后一切正常的Web Services,部署到另外一台2003的服务器上,出现两个问题:

1、Critical Error:

…没有权限访问注册表

其实只是在写入EventLog的时候ASPNET的权限不够,不过奇怪的是把ASPNET和匿名帐户加入Administrator组,重启,好像权限还是不够>.<

查看其列出的跟踪堆栈,发现好像是Enterprise Library中ADO.NET连接数据库的问题,在网上查了查,有用的文章不多,最后居然就在EntLib的FAQ里,发现是没有正确部署EnterLib程序集的问题。

安装程序工具(Installutil.exe)
允许通过执行指定程序集的安装程序组件来安装和卸载服务器资源。
注意: 在“%windir%Microsoft.NETFrameworkv1.1.xxxx”中可以找到Installutil.exe,其中xxxx是您使用的 .NET Framework 的内部版本号。

Installutil Microsoft.Practices.EnterpriseLibrary.Common.dll
Installutil Microsoft.Practices.EnterpriseLibrary.Configuration.dll
Installutil Microsoft.Practices.EnterpriseLibrary.Data.dll

一切恢复正常。

不过还是不知道为什么他的程序集部署的时候必须Install,而自己的dll就不用这一步。

PS:
删除用
Installutil /u xxx.dll

2、localhost访问没有问题,但用www.xxx.com访问,出错

在 .NET Framework 1.1 远程环境中,默认情况下 HTTP GET 和 HTTP POST 同时被禁用。这是出于安全方面的考虑。
当 Web 服务升级到 .NET Framework 1.1 后,应用程序使用 HTTP GET 或 HTTP POST 调用 Web 服务时会失败。
这些应用程序会收到以下一条错误信息 System.Net.WebException指出无法识别请求格式。

由于使用POST,现在已基本不可能转成SOAP协议,只有将其打开,更改Web.Config文件:
<configuration>
<system.web>
<webServices>
<protocols>
<!--
<add name="HttpGet">
-->
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>
</configuration>