目录
3.1 WebCliet.UploadFile( )方法的应用 4
7.1 如何通过App.config文件配置程序(App.config的读取)? 10
7.2 如何改写App.config文件,以实现配置信息的更新? 10
8. 为什么采用"PUT"上传时出现不用访问服务器即可上传的现象? 12
9. 为什么采用UploadFile()方法上传的图片不能用Windows图片传真浏览器预览? 13
修订历史记录
1. 什么是Winform客户端上传程序?
平常我们接触到的上传程序多是基于Web的,就是以网页的形式展现给客户。所使用的方法:
在Web 页的Request对象中包含有Files这个对象,里面就包含了通过POST方式上传的所有文件的信息,这时所需要做的就是调用 Request.Files[i].SaveAs方法。
Winform上传程序是指以Windows窗体的形式,来实现将文件上传到指定服务器的上传程序。那么怎样模拟Web Form POST 数据呢,System.Net命名空间里面提供了两个非常有用的类,一个是WebClient,另外一个是HttpWebRequest类。如果我们不需要通过代理服务器来上传文件,那么非常简单,只需要简单的调用WebClient.UploadFile方法就能实现上传文件。
2. 怎样实现与服务器的连接?
2.1 FTP服务器的连接
在 .NET 2.0 中, 提供了非常实用的FtpWebRequest(FtpWebResponse)类,因此与FTP服务器的通信十分方便,但是因为:
(1)FTP服务器的部署相对麻烦,还要设置权限,权限设置不对,还会惹来一系列的安全问题。
(2)如果双方都还有防火墙,又不想开发FTP相关的一些端口时,HTTP就会大派用场,就像WEB Services能穿透防火墙一样。
等一些原因,HTTP上传用处更为广泛。因此,FTP上传不做过多说明。
2.2 HTTP服务器的连接
在客户端上传程序中,通过UpLoadFile方法对服务器发出请求:
mWebClient.UploadFile(server+Path.GetFileName(filepath),"POST",filepath);
服务器端程序进行响应并将上传的文件通过SaveAs方法保存在制定路径。
3. 采用什么方法上传?
3.1 WebCliet.UploadFile( )方法的应用
WebClient位于System.Net类中,UpLoadFile的具体说明如下:
WebClient.UploadFile 方法 (Uri, String, String)
C#
public byte[] UploadFile (
Uri address,
string method,
string fileName
)
返回值
一个 Byte 数组,它包含来自资源的响应的正文。
具体参数:
address
接收文件的资源的 URI。
method
用于将文件发送到资源的 HTTP 方法。如果为空,则对于 http 默认值为 POST,对于 ftp 默认值为 STOR。
fileName
要发送到资源的文件。
4. 如何获得文件基本信息?
4.1 文件路径及文件名的获得
通过OpenFileDialog控件来对文件进行操作,首先创建一个dlg实例:
OpenFileDialog dlg = new OpenFileDialog ();
然后即可通过访问FileName属性得到文件的路径了:
string filepath=this.dlg.FileName;
如果希望获得文件的名字,而不是包含路径名,则可以通过下面的代码实现:
for(int i=filepath.Length -1;filepath[i]!='\\';i--)
index=i;
fname=filepath.Substring (index,filepath.Length-index );
原理:从filepath的最后一个字符向前遍历,遇到第一个'\'符号即停止循环,此时即可通过Substring()方法获得文件名。
此外,文件的扩展名可通过Path.GetExtension(filepath )方法来获得,其中Path属于System.IO。
4.2 文件大小的获得
文件大小的获得可以通过构造System.IO.FileInfo类,然后访问其Lengh属性即可。具体实现如下:
FileInfo fi=new FileInfo (dlg.FileName );
//将文件大小以KB为单位显示
long size=fi.Length/1024;
FileInfo构造器接受文件的绝对路径。
5. 怎样实现图像的预览功能?
5.1 对文件扩展名的判断
为了能够合理的显示图像,必须对打开的文件进行扩展名的判断,筛选出PictureBox能显示的图像。可以通过文件扩展名与.jpg .jpeg .bmp 等比较。获得扩展名可以通过Path.GetExtension(filepath )方法。
5.2 pictureBox控件的应用
在窗体中创建PictureBox空间后,可以通过如下设置来预览图片:
pictureBox1.Visible =true;
pictureBox1.Image =Image.FromFile (dlg.FileName);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
其中,Image属性用来设置显示的图片,Image.FromFile()方法来给出图像文件的来源,它就收一个String参数。
SizeMode属性来设置显示模式:
Normal : 默认属性;
Autosize: 随图片大小变化;
CenterImage:中心显示图片;
StretchImage:图片大小由PictureBox的大小决定;
5.3 处理非图像类文件
对于非图像文件,设置pictureBox1.Image =null,同时在预览框中显示用户提示信息,比如"没有预览"。此时由于PictureBox与Label会重合,所以一个可见时,应该将另一个控件的属性设置为不可见!
6. 如何实现拖曳上传功能?
6.1 如何响应文件被拖曳到窗体事件?
如果允许拖曳上传,就必须将窗体的AllowDrop 属性设置为true,然后为窗体添加委托:
this.DragDrop += new DragEventHandler(this.Form1_DragDrop);
this.DragEnter += new DragEventHandler(thisForm1_DragDropr);
其中Form1_DragDrop和Form1_DragDrop为两个方法,原型如下:
private void Form1_DragDrop(object sender, DragEventArgs e)
{
// Handle FileDrop data.
if(e.Data.GetDataPresent(DataFormats.FileDrop) )
{
//当有文件拖曳至窗口时,将文件信息存放于file中,其中file 【0】为文件的路径
string[] file=(string[])e.Data .GetData (DataFormats.FileDrop );
this.textBox2.Text =file[0];
button2.Enabled =true;
string exname=Path.GetExtension(file[0] ) ;
FileInfo fi=new FileInfo (file[0] );
long size=fi.Length/1024;
label5.Text ="文件大小: "+size.ToString ()+" KB";
if(exname.Equals(".jpg")||exname.Equals(".jpeg")||
exname.Equals(".bmp")||exname.Equals (".gif"))
{
pictureBox1.Visible =true;
pictureBox1.Image =Image.FromFile (file[0]);
pictureBox1.SizeMode=PictureBoxSizeMode.StretchImage;
label4.Visible=false;
}
else
{
label4.Visible =true;
pictureBox1.Visible =false;
label4.Text ="没有预览!";
}
}
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
//当文件被拖至窗体内,产生效果
// If the data is a file or a bitmap, display the copy cursor.
if (e.Data.GetDataPresent(DataFormats.Bitmap) ||
e.Data.GetDataPresent(DataFormats.FileDrop) )
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
这两个方法分别用来显示文件拖曳至窗体时的效果和产生的行为。红色字部分为重要提示。
6.2 拖曳文件路径的获得
当确实有文件被拖曳后,下列代码就会执行:
if(e.Data.GetDataPresent(DataFormats.FileDrop) )
{
//当有文件拖曳至窗口时,将文件信息存放于file中,其中file【0】为文件的路径
string[] file=(string[])e.Data .GetData (DataFormats.FileDrop );
.................
通过file[0]即可得到文件路径。
7. 什么是App.config文件?
App.config文件是程序的配置信息文件,会对程序运行时的一些参数进行配置,属于xml文件。在程序运行时,会从配置文件中得到有关参数,同时,也可以通过程序动态更新配置属性。具体的实现方法主要是通过System.Xml类的方法实现的。
7.1 如何通过App.config文件配置程序(App.config的读取)?
一个App.config文件的范例:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ConnenctionString" value="*" />
<add key="TmpPath" value="C:\Temp" />
</appSettings>
</configuration>
.Net提供了可以直接访问<appSettings>(注意大小写)元素的方法,在这元素中有很多的子元素,这些子元素名称都是"add",有两个属性分别是"key"和"value"。一般情况下我们可以将自己的配置信息写在这个区域中,通过下面的方式进行访问:
StringConString=System.Configuration.ConfigurationSettings.AppSettings["ConnenctionString"];
在AppSettings后面的是子元素的key属性的值,例如AppSettings["ConnenctionString"],我们就是访问<add key="ConnenctionString" value="*" />这个子元素,它的返回值就是"*",即value属性的值。
7.2 如何改写App.config文件,以实现配置信息的更新?
如果配置信息是静态的,我们可以手工配置,要注意格式。如果配置信息是动态的,就需要我们写程序来实现。在.Net中没有写配置文件的功能,我们可以使用操作XML文件的方式来操作配置文件。下面就是一个写配置文件的例子。
private void SaveConfig(string ConnenctionString)
{
XmlDocument doc=new XmlDocument();
//获得配置文件的全路径
string strFileName=AppDomain.CurrentDomain.BaseDirectory.ToString()+"Code.exe.config";
doc.Load(strFileName);
//找出名称为"add"的所有元素
XmlNodeList nodes=doc.GetElementsByTagName("add");
for(int i=0;i<nodes.Count;i++)
{
//获得将当前元素的key属性
XmlAttribute att=nodes[i].Attributes["key"];
//根据元素的第一个属性来判断当前的元素是不是目标元素
if (att.Value=="ConnectionString")
{
//对目标元素中的第二个属性赋值
att=nodes[i].Attributes["value"];
att.Value=ConnenctionString;
break;
}
}
//保存上面的修改
doc.Save(strFileName);
}
程序包含了命名空间System.Xml的类,因此必须对此类进行引用。代码中几个方法的使用:
string strFileName=AppDomain.CurrentDomain.BaseDirectory.ToString()+" Code.exe.config"
其中code要换成应用程序的名字!!
doc.Save(Path)方法接受文件的绝对路径,为string格式,将文件保存到制定的文件路径下。
8. 为什么采用"PUT"上传时出现不用访问服务器即可上传的现象?
最初上传时采用的代码:
mWebClient.UploadFile(@"http://localhost/Upload/Up.aspx","PUT",filepath);
结果出现文件上传成功但是文件名前都加上了Up.aspx,并且不用访问服务器。
注意:所有文件名前都加上了Up.aspx说明所有文件都传到了Upload文件夹,但是程序认为Up.aspx+文件名是真正的文件名。
在《C#高级编程(第4版)》第35章 "访问 Internet" 35.1.2目录下有这样一段信息:
在WebClient类中还有一个方法OpenWrite(),它可以返回一个可写的数据流,并把数据发送给URI。也可以指定该方法用于把数据发送给主机;默认方法是 POST 。下面的代码假定在本地机器上有一个可写的目录accept,这段代码将在该目录下创建文件newfile.txt,其内容为"Hello World":
WebClient webClient =new WebClient();
Stream stream=webClient.OpenWrite("http://localhost/accept/newfile.txt,"PUT");
StreamWriter streamWriter=new StreamWriter(stream);
streamWriter.WriteLine("Hello World");
streamWriter.Close();
从上面的代码以及说明可以看出,只要存在这样一个可以访问到并且允许写入的文件夹,PUT方法可以轻松的将文件写入,所以不必访问服务器。这也同时意味着服务器端对于本地上传的文件没有操作的权利,及无法改名,也无法将其另存为!
改变后的代码采用POST方法:
mWebClient.UploadFile(@"http://localhost/Upload/Up.aspx?","POST",filepath);
并且要在页面后面加上参数才会去访问服务器,并且必须使用POST方法,文件上传成功,而且服务器端程序可以将文件另存。
9. 为什么采用UploadFile()方法上传的图片不能用Windows图片传真浏览器预览?
上传的文本文件能够正常察看,但是图片却不能察看(用ACDsee可以看)。出现这个问题的原因是UploadFile()用于把指定的文件上传到指定的位置,而UploadData()方法用于把二进制的数据上传。而图片为二进制数据。