将Infopath附件上传到Sharepoint

时间:2011-07-13 20:53:21

标签: jquery sharepoint file-upload infopath

在我看到将infopath中的附件上传到sharepoint库的极少数方法中,没有一种看起来非常简单,而且所有这些都涉及服务器端代码。我从所有这些中听到的是,文件存储在表格的xml模板内的base64加密。

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

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

2 个答案:

答案 0 :(得分:0)

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

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

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

此外,我认为您正在尝试通过破解页面的HTML呈现来更改与Forms Server一起打开的XML。我不会这样做:

  • 当表单服务器呈现表单时,浏览器中没有XML
  • 附件不会发送到HTML页面
  • 没有足够的人可以帮助你
  • 显然不支持

答案 1 :(得分:0)

我找到了一个在页面后面使用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足够简单<div id="response"></div>只是为了接收数据。

这是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进行一些研究。你需要改变它。
  • 这仅为包含信息表格的文档库中的每个附件提供了下载链接。您当然可以使用参数化查询来过滤某些数据。