2012-01-05 9 views
0

共有ドライブ上のファイルを選択するためのWebベースのソリューションを提供しようとしています。 ファイルを参照するときにWindowsによって提供される典型的なファイルセレクタを使用したいと思います。私がこれから必要とする唯一の情報は完全なファイル名+パスです。今すぐ明らかな解決策は、ユーザーがファイル名を入力するフリーテキストのテキストボックスを持つことですが、ファイルセレクタを使用する必要があります。 (下の画像)共有フォルダのファイルをブラウズし、クライアントが選択したフルパスを返します。ファイルをアップロードせずに

私はTelerikコントロールを使用していますが、このダウンロード機能は親ページのajaxifiedパネル内にあるユーザーコントロールにあります。

file selection dialog

現在、私は、このマークアップを持っている:背後

Add a Link to a Document: <input type="file" id="upLink" runat="server" onchange="LinkSelected(this);" /> 
<asp:HiddenField ID="hdnLinkFile" runat="server" /> 
<asp:Button ID="btnLink" runat="server" CssClass="invisiblebutton" OnClick="LinkFile" /> 

<script> 
    function LinkSelected(sender) { 
     if (sender && sender.value.length > 0) { 
      //save filename to hidden value as it will not otherwise be usable on the server without a postback 
      $("#<%= hdnLinkFile.ClientID %>").val(sender.value); 
      //clear 
      sender.value = null; 
      //fire server request on this user control 
      $find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>").ajaxRequestWithTarget("<%= btnLink.UniqueID %>", ""); 
     } 
    } 
</script> 

コード:

protected void LinkFile(object sender, EventArgs e) 
{ 
    if (hdnLinkFile.Value.Length > 2 && hdnLinkFile.Value.Substring(0, 2) != @"\\") 
    { 
     Code.Common.DisplayMessage("File must be in a shared location!", Page); 
    } 
    else 
    { 
     //save link string to database 
    } 
} 

このコードの目的は、完全なポストバックを防ぐためです。完全なポストバックにより、ファイル入力(upLink)によって選択されたファイルがWebサーバーにアップロードされます。大きなファイル(100MB以上)をリンクできるようになり、私が望むのはファイルパスです(クライアントのインターネットの一部は非常に遅いです)。アップロードする必要はありません。

このコードはIEでうまくいきます - 残念ながら、type = fileの入力では、Firefoxは完全なパス名ではなくファイル名のみを返します。そのため、Firefoxはこのデータをセキュリティ上のリスクとみなしているだけでなく、クライアントがデフォルトでFirefoxを使用しているため、別の方法を見つける必要があります。私が望むのは、実際にファイルをアップロードせずに完全なファイル名+パスです。どれだけ難しいでしょうか?

+2

セキュリティ上の理由から、パスは指定されていません。ページが正しいセキュリティゾーンにない限り、IEはそれを与えません。 – epascarello

+0

epascarlloによれば、これは設計上のセキュリティ上の制限です。 IEはlocalhostマシンでテストしたか、またはインターネットゾーン(または他の制限ゾーン)にいなかったために動作しました。 「ファイルアップロードコントロール」のセクションには、http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspxの情報があります。クライアントの完全パスを要求する理由はあまりありません。そのため、特にパスを必要としていることがありますか? – keyboardP

+0

[MSDN](http://msdn.microsoft.com/en-us/library/ms535263(v = vs.85).aspx)の注釈セクションを参照してください。Mozillaには[File Object](https:// developer .mozilla.org/en/DOM/File)でも、パスの取得にはまだ制限があります。 – epascarello

答えて

0

私はそれを行う方法を見つけた唯一の方法は、自分のファイルセレクタダイアログを構築することでした。私がすでにTelerikコントロールを使用しているのを見て、RadTreeViewとRadWindowを以下のように使用しました。私はそれをより簡単にするためにすべてのバリデーションを引き出しました。そのTelerikデモに基づいてhere


Explorer.aspx

<script type="text/javascript"> 
    function onNodeClicking(sender, args) { 
     //fill path textbox 
     var textbox = document.getElementById('inpPath'); 
     if (args.get_node()._parent._uniqueId == "RadTreeView1") 
     textbox.value = args.get_node()._properties._data.value; //root node 
     else 
     textbox.value = args.get_node()._parent._properties._data.value + "\\" + args.get_node()._getData().text; 
    } 

    function onCancel() { 
     var wnd = getRadWindow(); 
     var openerPage = wnd.BrowserWindow; 
     openerPage.OnFileSelected(''); 
     wnd.close(); 
    } 

    function onOK() { 
     var wnd = getRadWindow(); 
     var openerPage = wnd.BrowserWindow; 
     openerPage.OnFileSelected(document.getElementById('inpPath').value); 
     wnd.close(); 
    } 

    function getRadWindow() { 
     var oWindow = null; 
     if (window.radWindow) oWindow = window.radWindow; 
     else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow; 
     return oWindow; 
    } 
</script> 

<div id="divFolderPath" style="padding: 0px 0px 10px 10px;"> 
    <input id="inpPath" runat="server" type="text" style="width:80%;" />&nbsp;&nbsp; 
    <asp:Button ID="btnGo" runat="server" Text="Go" onclick="btnGo_Click" /> 
</div> 

<div id="divButtons" style="padding: 0px 0px 15px 10px; text-align:center;"> 
    <input id="btnOk" type="button" value="OK" onclick="onOK()" style="padding-right:5px;" disabled="disabled" /> 
    <input id="btnCancel" type="button" value="Cancel" onclick="onCancel()" /> 
</div> 

<telerik:RadTreeView ID="RadTreeView1" runat="server" 
    OnNodeExpand="RadTreeView1_NodeExpand" 
    OnClientNodeClicking="onNodeClicking"> 
</telerik:RadTreeView> 




コードの後ろに(ポップアップウィンドウ):

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Linq; 
using System.Web.UI; 
using System.IO; 
using Telerik.Web.UI; 

//extensions we have pics for 
private readonly string[] _knownExtensions = new[] { "csv", "doc", "docx", "gif", "html", "jpg", "pdf", "png", "txt", "xls", "xlsx", "xml" }; 

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
     if (Session["nodes"] != null && ((List<string>)Session["nodes"]).Count > 0) 
     { 
     foreach (string nod in (List<string>)Session["nodes"]) 
     { 
      AddNode(nod); 
     } 
     } 
     else 
     { 
     AddNode(ConfigurationManager.AppSettings["LinkDocumentStartPath"]); 
     } 
    } 
} 

private void AddNode(string rootpath) 
{ 
    Directory.GetDirectories(rootpath); 
    inpPath.Value = rootpath; 
    //won't get this far if it fails the first check 
    var dirNode = new RadTreeNode(rootpath) 
    { 
     Value = rootpath, 
     ImageUrl = "~/Content/Images/folder.png", 
     Expanded = true, 
     ExpandMode = TreeNodeExpandMode.ServerSideCallBack 
    }; 
    dirNode.Attributes.Add("isFile", "false"); 
    RadTreeView1.Nodes.Add(dirNode); 
} 

protected void RadTreeView1_NodeExpand(object sender, RadTreeNodeEventArgs e) 
{ 
    BindTreeToDirectory(e.Node.Value, e.Node); 
} 

private void BindTreeToDirectory(string path, RadTreeNode parentNode) 
{ 
    //get directories 
    string[] directories = Directory.GetDirectories(path); 
    foreach (string directory in directories) 
    { 
     var dirNode = new RadTreeNode(Path.GetFileName(directory)) 
     { 
     Value = path + "/" + Path.GetFileName(directory), 
     ImageUrl = "~/Content/Images/folder.png", 
     ExpandMode = TreeNodeExpandMode.ServerSideCallBack 
     }; 
     dirNode.Attributes.Add("isFile","false"); 
     parentNode.Nodes.Add(dirNode); 
    } 
    //get files in directory 
    string[] files = Directory.GetFiles(path); 
    foreach (string file in files) 
    { 
     var node = new RadTreeNode(Path.GetFileName(file)); 
     node.Attributes.Add("isFile", "true"); 
     //get extension 
     string extension = Path.GetExtension(file); 
     if (!string.IsNullOrEmpty(extension)) 
     { 
     extension = extension.ToLower().TrimStart('.'); 
     } 
     //choose an image for the extension 
     if (Array.IndexOf(_knownExtensions, extension) > -1) 
     { 
     node.ImageUrl = "~/Content/Images/" + extension + ".png"; 
     } 
     else 
     { 
     node.ImageUrl = "~/Content/Images/unknown.png"; 
     } 
     parentNode.Nodes.Add(node); 
    } 
} 

//go to a new directory 
protected void btnGo_Click(object sender, EventArgs e) 
{ 
    string nod = inpPath.Value.Trim(); 
    if (!string.isNullOrEmpty(nod)) 
    { 
     var nodeslst = new List<string>(); 
     if (Session["nodes"] != null) 
     { 
     nodeslst = (List<string>) Session["nodes"]; 
     } 
     else 
     { 
     //session has expired - get nodes from radtree 
     nodeslst.AddRange(from RadTreeNode rtn in RadTreeView1.Nodes select rtn.Value); 
     } 
     if (nodeslst.Contains(nod, StringComparer.OrdinalIgnoreCase) == false) 
     { 
     AddNode(nod); 
     nodeslst.Add(nod); 
     } 
     Session["nodes"] = nodeslst; 
    } 
} 



と、このコードは、ファイル選択ボタンがあるページに行く:あなたはそれは次のようになり見ることができるように

protected void LinkFile(object sender, EventArgs e) 
{ 
    if (!string.IsNullOrEmpty(txtLinkFileName.Text)) 
    { 
     if (txtLinkFileName.Text.Length > 2 && txtLinkFileName.Text.Substring(0, 2) != @"\\") 
     { 
     Code.Common.DisplayMessage("File must be in a shared location!", Page); 
     } 
     else 
     { 
     //just a link to a file - no need to upload anything 
     //save filepath to database 
     //filepath = txtLinkFileName.Text; 
     } 
    } 
} 

:背後

<span style="width:200px; display:inline-block; text-align:right; padding-right:5px;">Add a Link to a Document:</span> 
<telerik:RadTextBox ID="txtLinkFileName" runat="server" Width="325px" Enabled="False"></telerik:RadTextBox> 
<asp:Button ID="selectFile" OnClientClick="OpenFileExplorerDialog(); return false;" Text="Browse..." runat="server" /> 

<asp:Button ID="btnLink" runat="server" CssClass="invisiblebutton" OnClick="LinkFile" CausesValidation="false" /> 

<telerik:RadWindow runat="server" Width="550px" Height="560px" VisibleStatusbar="false" 
    ShowContentDuringLoad="false" NavigateUrl="Explorer.aspx" ID="ExplorerWindow" 
    Modal="true" Behaviors="Close,Move,Resize"> 
</telerik:RadWindow> 

<script type="text/javascript"> 
    function OpenFileExplorerDialog() { 
     var wnd = $find("<%= ExplorerWindow.ClientID %>"); 
     wnd.show(); 
    } 

    //This function is called from code on the Explorer.aspx page 
    function OnFileSelected(fileSelected) { 
     if (fileSelected && fileSelected.length > 0) { 
      var textbox = $find("<%= txtLinkFileName.ClientID %>"); 
      textbox.set_value(fileSelected); 
      $find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>").ajaxRequestWithTarget("<%= btnLink.UniqueID %>", ""); 
     } 
    } 
</script> 



コードをスマートタイプのブラウザが自分自身から私たちを守ろうとするのではなく、それでも達成可能であれば、もっと簡単になります。

関連する問題