【问题标题】:Upload Infopath attachment to Sharepoint将 Infopath 附件上传到 Sharepoint
【发布时间】:2011-07-22 01:19:14
【问题描述】:

在我见过的几种将 infopath 中的附件上传到共享点库的方法中,没有一种方法看起来很简单,而且都涉及服务器端代码。我从所有这些中听到的是,该文件以 base64 加密方式存储在表单的 xml 模板中。

我对共享点页面上表单的 DOM 有完整的 javascript/jQuery 访问权限,但我很难找到这个 base64 字符串的确切位置。

注意,我试图在提交表单之前获取附件的 base64,我假设它在 DOM 中的某个地方,但我不知道在哪里。任何帮助表示赞赏。

【问题讨论】:

    标签: jquery sharepoint file-upload infopath


    【解决方案1】:

    首先 - 确保您没有将 InfoPath 文档的 XML DOM 与 HTML 页面的 HTML DOM 混合。

    第二 - 在谈到 InfoPath 时:“XML 模板”是存储在 XSN 中并用作此 XSN 表单的初始(空白)文档的 XML。由于您说的是“在提交表单之前”,我假设您实际上是在谈论使用此 XSN 创建的 XML 文档(表单)。

    可以直接使用 JavaScript 将附件添加到存储在文档库中的 InfoPath XML 文档(从服务器打开 XML,替换节点的值,将其保存回来)。代码将比 C#/VB.Net 中的服务器端代码稍微复杂一些,所以...使用 XPath 或 JQuery 查找节点应该不会太难,但它是特定于表单的。

    此外,我认为您正试图通过破解页面的 HTML 呈现来更改当前使用 Forms Server 打开的 XML。我不会那样做:

    • Forms Server 渲染表单时浏览器中没有 XML
    • 附件根本不会发送到 HTML 页面
    • 没有足够的人可以为您提供帮助
    • 显然不支持

    【讨论】:

    • 我实际上想出了一个比任何提议的方法都好得多的方法,我应该把它作为这个问题的答案发布吗?
    【解决方案2】:

    我找到了一个在页面后面使用 jQuery 和 C# 代码的解决方案。这是jQuery部分:

    $.getJSON('_vti_bin/listdata.svc/<NAME OF LIST (FORMATTED FOR LISTDATA.SVC)>', function(data){
      $.each(data.d.results, function(index, value){
        $.get('<NAME OF LIST>/'+value.Title+"?noredirect=true", function(info){
          $.post('<PATH TO filecreator.aspx>, {file: $(info).find('[nodeName="my:memo"]').text()}, function(data){
            $('#response').html(data);
          });
        });
      });
    });
    

    html 是一个足够简单的&lt;div id="response"&gt;&lt;/div&gt;,只是用来接收数据。

    这里是 filecreator.aspx 文件:

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Web" %>
    <%@ Import Namespace="System.IO" %>
    <%@ Import Namespace="System.Text" %>
    <script runat="server">
      public void Page_Load(object sender, EventArgs e){
        int fileSize, nameLength;
        string name = "";
        byte[] decodedData;
        HttpContext c = HttpContext.Current;
        string data64 = c.Request["file"];
        if(data64==""){
          return;
        }
        byte[] data = Convert.FromBase64String(data64);
        using(MemoryStream ms = new MemoryStream(data)){
          BinaryReader reader = new BinaryReader(ms);
          byte[] header = new byte[16];
          header = reader.ReadBytes(header.Length);
    
          fileSize = (int)reader.ReadUInt32();
          nameLength = (int)reader.ReadUInt32() * 2;
    
          byte[] fileName = reader.ReadBytes(nameLength);
          Encoding enc = Encoding.Unicode;
          name = enc.GetString(fileName, 0, nameLength -2);
          decodedData = reader.ReadBytes(fileSize);
        }
        string filePath = Server.MapPath("/temp/"+name);
        if(File.Exists(filePath)){
            File.Delete(filePath);
        }
        FileStream fs = new FileStream(filePath, FileMode.CreateNew);
        BinaryWriter writer = new BinaryWriter(fs);
        writer.Write(decodedData);
    
        writer.Close();
        fs.Close();
        Response.Write("<a href=\"http://sharept03sb1/services/?download.aspx?file="+name+"\">"+name+"</a><br />");
      }
    </script>
    

    最后,这是开始下载的 download.aspx 文件,它现在容易受到 lfi 的攻击,我将标记应该修复的位置:

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Web" %>
    <%@ Import Namespace="System.IO" %>
    <%@ Import Namespace="System.Text" %>
    <script runat="server">
      public void Page_Load(object sender, EventArgs e){
        string name = Request.QueryString["file"]; // HERE: Make sure to prevent lfi via directory traversal :)
        FileStream fs = File.Open(Server.MapPath("/temp/"+name), FileMode.Open);
        byte[] file = new byte[fs.Length];
        fs.Read(file, 0, Convert.ToInt32(fs.Length));
        fs.Close();
        Response.AddHeader("Content-disposition", "attachment; filename=" + name);
        Response.ContentType = "application/octet-stream";
        Response.BinaryWrite(file);
        Response.End();
      }
    </script>
    

    几个提示:

    • 如果您遇到有关代码块不起作用的问题,请确保对 sharepoint 的 web.config 文件中的 PageParserPaths 进行一些研究。你需要改变它。
    • 这只会为包含信息路径表单的文档库中的每个附件提供下载链接。您当然可以使用参数化查询来过滤某些数据。

    【讨论】:

      猜你喜欢
      • 2018-08-24
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 2019-07-19
      • 1970-01-01
      相关资源
      最近更新 更多