Просмотрите файлы в общей папке и верните полный путь, выбранный клиентом, БЕЗ загрузки файла - PullRequest
0 голосов
/ 05 января 2012

Я пытаюсь предоставить пользователям веб-решение для выбора файла на общих дисках. Я хочу использовать типичный селектор файлов, который предоставляется окнами, когда вы идете, чтобы найти файл. Единственная информация, которая мне нужна, это полное имя файла + путь. Теперь очевидным решением было бы просто иметь текстовое поле со свободным текстом, где пользователи вводят свое имя файла, но я должен использовать селектор файлов. (изображение ниже)

В качестве примечания я использую элементы управления Telerik, и эта функция загрузки находится в пользовательском элементе управления, который находится внутри отрегулированной панели на родительской странице.

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) загружает выбранный файл на веб-сервер. Поскольку мы разрешаем связывать большие файлы (более 100 МБ), и все, что мне нужно, это путь к файлу (а интернет для некоторых клиентов очень медленный), загрузка не нужна.

этот код прекрасно работает в IE - к сожалению, для входных данных с типом = файл Firefox возвращает только имя файла, а не полный путь + имя. Поскольку Firefox не предоставляет эти данные, так как это считается угрозой безопасности, а также то, что клиент использует Firefox по умолчанию, мне нужно найти другой способ. Все, что я хочу, это полное имя файла + путь, без фактической загрузки файла - насколько сложно это может быть ???

1 Ответ

0 голосов
/ 17 января 2012

Ну, к сожалению, единственный способ, которым я нашел, как это сделать - это создать собственный диалог выбора файлов. Поскольку я уже использую элементы управления Telerik, я использовал RadTreeView и RadWindow, как показано ниже. Я вытащил все проверки, чтобы сделать это проще. Он основан на демо Telerik здесь


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;
   }
}



и этот код переходит на страницу с кнопкой выбора файла:

<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;
      }
   }
}

Как видите, было бы намного проще, если бы умные браузеры не пытались защитить нас от самих себя, но все же достижимы.

...