zoukankan      html  css  js  c++  java
  • silverlight使用js和asp.net上传文件[绕过silverlight的安全限制]

    silverlight上传附件是许多系统需要的功能,但是silverlight暂时还存在着安全限制,作为浏览器的插件,它是不能直接访问客户端本地的文件的,即使网上有说用OpenFileDialog可以实现访问本地文件,但经过我测试是行不通,总是会有限制访问的错误报出来。
    于是换个思维,使用asp.net的FileUpload控件实现文件的上传,再将上传的文件的文件名传回silverlight做相关的处理。
    这个方法的大概思想是:
    1.silveright页面按钮调用承载页的js代码打开一个用于上传的aspx页面,文件的上传都是在这个页面中完成。
    2.文件上传完成以后,上传页将上传的文件的文件名传回承载页,再由承载页传回silverlight,以完成其它的工作。
    具体实现如下:
    1.首先这个方法需要silverlight与承载页的js代码进行交互,所以必须完成以下的基础操作:
    1 void FileUploader_Loaded(object sender, RoutedEventArgs e)
    2 {
    3 HtmlPage.RegisterScriptableObject("FileUploadCtrl", this);
    4 }
    在需要调用承载页的loaded事件中将本silverlight页面注册为脚本对象,这样承载页中的js代码就可以使用本页的后台代码中具有ScriptableMember特性的方法了,如以下方法:
     
    1 [ScriptableMember]
    2 public void SetSelectedFile(string fullName)
    3 {
    4 SelectedFileName = fullName;
    5 }
    这个方法是给承载页的js代码将上传文件的文件名传回silverlight。
    在承载中定义如下的函数
    1 function UploadFile() {
    2 //打开文件上传页面
    3   window.open('FileUpload.aspx', '上传附件', 'height=30,width=300, toolbar=no, menubar=no,location=no, status=no');
    4 }
    5 function SetSelectedFile(fullname) {
    6 //将上传文件的文件名传回silverlight
    7   var control = document.getElementById("SilverlightControl");
    8 var manager = control.Content.FileUploadCtrl;
    9 manager.SetSelectedFile(fullname);
    10 }
    11 function OpenAffix(msg) {
    12 //打开文件
    13   if (arguments.length > 0) {
    14 window.open("UploadFiles/" + arguments[0], "_blank");
    15 }
    16 }
    2.完成以上工作以后则可以进行以下的操作。
    在页面中放一个按钮,点击事件这么写:
    1 public void Button_Click(object sender, RoutedEventArgs e)
    2 {
    3 try
    4 {
    5 ScriptObject sobjUploadFile = HtmlPage.Window.GetProperty("UploadFile") as ScriptObject;
    6 sobjUploadFile.InvokeSelf();
    7 return;
    8 }
    9 catch (Exception ex)
    10 {
    11 MessageBox.Show(ex.Message);
    12 }
    13 }
    第5行中GetProperty的参数即为承载页定义的js函数的函数名。运行这段代码就可以调用承载页的UploadFile的方法,即打开FileUpload.aspx页面。
    3.FileUpload.aspx页面的内容如下:
    1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUpload.aspx.cs" Inherits="OIU.Web.FileUpload" %>
    2
    3  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4
    5  <html xmlns="http://www.w3.org/1999/xhtml">
    6  <head runat="server">
    7 <title></title>
    8 <script type="text/javascript">
    9 function SetSelectedFile(fullName) {
    10 window.opener.location = "javascript:SetSelectedFile('" + fullName + "');";
    11 window.close();
    12 }
    13 </script>
    14  </head>
    15  <body>
    16 <form id="form1" runat="server">
    17 <div>
    18 <asp:FileUpload runat="server" ID="fu" />
    19 &nbsp;<asp:Button Text="上传" runat="server" ID="btnUpload"
    20 onclick="btnUpload_Clicked" />
    21 </div>
    22 </form>
    23  </body>
    24  </html>
    这里注意,第9行的js函数,通过window.opener来调用打开这个页面的父页面的js方法:SetSelectedFile。
    上传按钮的点击事件处理函数这么写:
    1 protected void btnUpload_Clicked(object sender, EventArgs e)
    2 {
    3 if (fu.HasFile)
    4 {
    5 if (fu.PostedFile.ContentLength / 1024 / 1024 > 5)
    6 {
    7 ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>alert('文件过大,支持最大5M的文件上传');</script>");
    8 return;
    9 }
    10 //string uploadFullName = string.Format("{0}UploadFiles\\{1}", AppDomain.CurrentDomain.BaseDirectory, fu.FileName);
    11 string uploadFullName = Server.MapPath("~/UploadFiles/") + fu.FileName;
    12 fu.SaveAs(uploadFullName);
    13 //将文件全路径返回父页面
    14 ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>SetSelectedFile('" + fu.FileName + "');</script>");
    15 }
    16 else
    17 {
    18 ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>alert('新先选择要上传的文件');</script>");
    19 }
    20 }
    21 }
    里面有一部分的验证操作。开始我是想将上传的全路径传给页面再传回silverlight的,但是,从后台调用前台js函数时参数的路径分隔符全被转义了,如果谁能解决这个问题,可以跟帖让我学习学习。
    4.完成了以上的操作以后,文件就已经上传到了服务器指定的目录了,接下来的工作就是如何下载或者打开上传的文件。
    我的实现方法是通过silverlight页面文本的点击,调用承载页的OpenAffix函数使用打开文件。具体实现如下:
    1 private void StatusText_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    2 {
    3 if (null != StatusText.Tag && !string.IsNullOrEmpty(StatusText.Tag.ToString()))
    4 {
    5 HtmlPage.Window.Invoke("OpenAffix", StatusText.Tag);
    6 }
    7 }
    这是另一种silverlight调用承载页js函数的方法。参考第1条中js函数,可以实现文件的下载或者打开。
  • 相关阅读:
    loj#2333 「JOI 2017 Final」准高速电车
    loj#2332 「JOI 2017 Final」焚风现象
    loj#501 「LibreOJ β Round」ZQC 的树列
    loj#500 「LibreOJ β Round」ZQC 的拼图
    p2827 蚯蚓
    p5471 [NOI2019]弹跳
    p5304 [GXOI/GZOI2019]旅行者
    p2503 [HAOI2006]均分数据
    p4899 [IOI2018] werewolf 狼人
    loj#137 最小瓶颈路 加强版
  • 原文地址:https://www.cnblogs.com/larson/p/2057212.html
Copyright © 2011-2022 走看看