我正在尝试为用户提供基于Web的解决方案,以便在共享驱动器上选择文件。 我想在你去浏览文件时使用windows提供的典型文件选择器。我需要的唯一信息是完整的文件名+路径。现在一个明显的解决方案是只有一个自由文本文本框,用户输入文件名,但我需要使用文件选择器。 (如下图所示)
作为旁注,我正在使用Telerik控件,此下载功能位于父页面中ajaxified面板内的用户控件中。
目前我有这个标记:
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,我需要找到另一种方式。我想要的只是完整的文件名+路径,而不是实际上传文件 - 它有多难?
答案 0 :(得分: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%;" />
<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;
}
}
,此代码位于包含文件选择按钮的页面上:
<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>
代码背后:
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;
}
}
}
正如你所看到的,如果smartypants浏览器不是试图保护我们自己,但仍然可以实现,那将会容易得多。