最近在做一个大文件断点续传的控件,有试过纯C#的代码来写,但后来发现是在是太不灵活了,于是考虑使用控件。但在控件开发过程中发现,如何获取上传文件的物理路径是个大问题,因为Silverlight不支持获取客户端路径的,不仅是Silverlight,所有的微软上传控件都不支持获取本地物理路径。于是我就各种查,终于发现有种方法可以获取到文件的信息了。
先看一个例子
1 #region 选择文件 2 private void bt_SelectFile_Click(object sender, RoutedEventArgs e) 3 { 4 OpenFileDialog ofd = new OpenFileDialog(); //初始化 5 ofd.Multiselect = true; //设置可以多选 6 ofd.Filter="请选择文件|‘*’"; //限制文件类型及提示 7 if (ofd.ShowDialog() == true) 8 { 9 foreach (FileInfo file in ofd.Files) 10 { 11 UserFile userFile = new UserFile(); //自定义的文件上传信息类 12 userFile.FileName = file.Name; //获取文件名 13 userFile.FileStream = file.OpenRead(); //以只读的方式打开文件 14 userFile.FilePhysicalpath = file.FullName; //在由受信任的应用程序调用时,获取目录或文件的完全路径名 15 userFile.FileTime = file.LastWriteTime; //在由受信任的应用程序调用时,获取文件的最后修改日期 16 } 17 } 18 } 19 #endregion
事实上,在我们调试的时候会发现,userFile.FilePhysicalpath = file.FullName; userFile.FileTime = file.LastWriteTime; 这两句代码会报错,提示说发现未经调试的异常。这是因为Silverlight在由微软的封装下不允许访问客户端的文件,怎么解决呢?其实很简单,在最新发布的Silverlight5的版本中,微软允许开发者在内部通过提升应用程序的信任度来获取本地文件操作的权限。
右击我们的Silverlight项目的属性,在Silverlight一栏下,我们可以看到
勾选【在浏览器内运行时需要提升的信任】,这样我们就可以操作本地文件啦!
这里需要说明一下在勾选了之后微软做的操作,因为有的时候我们勾选了还是不能获取文件的路径。
当你勾选“在浏览器内运行时需要提升的信任”时,visual studio会做下面几件事情:
1、在silverlight的项目文件(.csproj)中增加内容:<RequireInBrowserElevation>true</RequireInBrowserElevation>
2、在项目的Properties文件夹中增加一个文件:InBrowserSettings.xml。
3、在silverlight的项目文件(.csproj)中增加内容:<InBrowserSettingsFile>Properties/InBrowserSettings.xml</InBrowserSettingsFile>
详细情况请看我的另一篇文章Silverlight控件——如何提升应用程序信任度与问题解决
现在我们就可以在调试的时候获取到文件的路径啦。
好了,我们把项目发出到服务器上面去看看吧,咦?怎么还是获取不到呢?原来这是因为调试的时候是在本地,而发不到服务器上之后,是通过互联网访问的,也就是说,这是一个跨域的行为。聪明的你肯定想到了,对了,我们在编写一个可以跨域访问的脚本就行了撒。其实很简单,看下面
在我们的web项目下建立一个clientaccesspolicy.xml,代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <access-policy> 3 <cross-domain-access> 4 <policy> 5 <allow-from http-request-headers="*"> 6 <domain uri="*"/> 7 </allow-from> 8 <grant-to> 9 <resource path="/" include-subpaths="true"/> 10 </grant-to> 11 </policy> 12 </cross-domain-access> 13 </access-policy>
将 clientaccesspolicy.xml 文件保存到承载该服务的域的根目录中。例如,如果该服务在 http://fabrikam.com 上承载,则文件必须位于 http://fabrikam.com/clientaccesspolicy.xml。
另外再建立一个crossdomain.xml,代码如下:
1 <?xml version="1.0"?> 2 <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> 3 <cross-domain-policy> 4 <allow-http-request-headers-from domain="*" headers="*"/> 5 </cross-domain-policy>
将 crossdomain.xml 文件保存在承载服务的域的根目录中。例如,如果该服务在 http://fabrikam.com 上承载,则文件必须位于 http://fabrikam.com/crossdomain.xml。
详情请看使服务跨域边界可用
现在我们就可以在其他电脑打开网站输入网址,获取到我们本地文件的路径了。