在Workflow 中,签核完成后,在列表中生成一笔记录,并且将表单的附件附加到该记录中。
1. 新建 coder 类. http://support.microsoft.com/kb/892730
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace InfoPathAttachmentEncoding
{
/// <summary>
/// InfoPathAttachment encodes file data into the format expected by InfoPath for use in file attachment nodes.
/// </summary>
public class InfoPathAttachmentEncoder
{
private string base64EncodedFile = string.Empty;
private string fullyQualifiedFileName;
/// <summary>
/// Creates an encoder to create an InfoPath attachment string.
/// </summary>
/// <param name="fullyQualifiedFileName"></param>
public InfoPathAttachmentEncoder(string fullyQualifiedFileName)
{
if (fullyQualifiedFileName == string.Empty)
throw new ArgumentException("Must specify file name", "fullyQualifiedFileName");
if (!File.Exists(fullyQualifiedFileName))
throw new FileNotFoundException("File does not exist: " + fullyQualifiedFileName, fullyQualifiedFileName);
this.fullyQualifiedFileName = fullyQualifiedFileName;
}
/// <summary>
/// Returns a Base64 encoded string.
/// </summary>
/// <returns>String</returns>
public string ToBase64String()
{
if (base64EncodedFile != string.Empty)
return base64EncodedFile;
// This memory stream will hold the InfoPath file attachment buffer before Base64 encoding.
MemoryStream ms = new MemoryStream();
// Get the file information.
using (BinaryReader br = new BinaryReader(File.Open(fullyQualifiedFileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
string fileName = Path.GetFileName(fullyQualifiedFileName);
uint fileNameLength = (uint)fileName.Length + 1;
byte[] fileNameBytes = Encoding.Unicode.GetBytes(fileName);
using (BinaryWriter bw = new BinaryWriter(ms))
{
// Write the InfoPath attachment signature.
bw.Write(new byte[] { 0xC7, 0x49, 0x46, 0x41 });
// Write the default header information.
bw.Write((uint)0x14); // size
bw.Write((uint)0x01); // version
bw.Write((uint)0x00); // reserved
// Write the file size.
bw.Write((uint)br.BaseStream.Length);
// Write the size of the file name.
bw.Write((uint)fileNameLength);
// Write the file name (Unicode encoded).
bw.Write(fileNameBytes);
// Write the file name terminator. This is two nulls in Unicode.
bw.Write(new byte[] {0,0});
// Iterate through the file reading data and writing it to the outbuffer.
byte[] data = new byte[64*1024];
int bytesRead = 1;
while (bytesRead > 0)
{
bytesRead = br.Read(data, 0, data.Length);
bw.Write(data, 0, bytesRead);
}
}
}
// This memorystream will hold the Base64 encoded InfoPath attachment.
MemoryStream msOut = new MemoryStream();
using (BinaryReader br = new BinaryReader(new MemoryStream(ms.ToArray())))
{
// Create a Base64 transform to do the encoding.
ToBase64Transform tf = new ToBase64Transform();
byte[] data = new byte[tf.InputBlockSize];
byte[] outData = new byte[tf.OutputBlockSize];
int bytesRead = 1;
while (bytesRead > 0)
{
bytesRead = br.Read(data, 0, data.Length);
if (bytesRead == data.Length)
tf.TransformBlock(data, 0, bytesRead, outData, 0);
else
outData = tf.TransformFinalBlock(data, 0, bytesRead);
msOut.Write(outData, 0, outData.Length);
}
}
msOut.Close();
return base64EncodedFile = Encoding.ASCII.GetString(msOut.ToArray());
}
}
}
using System;
using System.IO;
using System.Text;
namespace InfoPathAttachmentEncoding
{
/// <summary>
/// Decodes a file attachment and saves it to a specified path.
/// </summary>
public class InfoPathAttachmentDecoder
{
private const int SP1Header_Size = 20;
private const int FIXED_HEADER = 16;
private int fileSize;
private int attachmentNameLength;
private string attachmentName;
private byte[] decodedAttachment;
/// <summary>
/// Accepts the Base64 encoded string
/// that is the attachment.
/// </summary>
public InfoPathAttachmentDecoder(string theBase64EncodedString)
{
byte [] theData = Convert.FromBase64String(theBase64EncodedString);
using(MemoryStream ms = new MemoryStream(theData))
{
BinaryReader theReader = new BinaryReader(ms);
DecodeAttachment(theReader);
}
}
private void DecodeAttachment(BinaryReader theReader)
{
//Position the reader to get the file size.
byte[] headerData = new byte[FIXED_HEADER];
headerData = theReader.ReadBytes(headerData.Length);
fileSize = (int)theReader.ReadUInt32();
attachmentNameLength = (int)theReader.ReadUInt32() * 2;
byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength);
//InfoPath uses UTF8 encoding.
Encoding enc = Encoding.Unicode;
attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2);
decodedAttachment = theReader.ReadBytes(fileSize);
}
public void SaveAttachment(string saveLocation)
{
string fullFileName = saveLocation;
if(!fullFileName.EndsWith(Path.DirectorySeparatorChar))
{
fullFileName += Path.DirectorySeparatorChar;
}
fullFileName += attachmentName;
if(File.Exists(fullFileName))
File.Delete(fullFileName);
FileStream fs = new FileStream(fullFileName, FileMode.CreateNew);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(decodedAttachment);
bw.Close();
fs.Close();
}
public string Filename
{
get{ return attachmentName; }
}
public byte[] DecodedAttachment
{
get{ return decodedAttachment; }
}
}
}
2. 读取并上传 http://zhonglei.blog.51cto.com/1159374/268587
XPathNavigator ipFormNav = MainDataSource.CreateNavigator();
XPathNavigator nodeNav = ipFormNav.SelectSingleNode("//my:document", NamespaceManager);
string attachmentValue = string.Empty;
if (nodeNav != null && !String.IsNullOrEmpty(nodeNav.Value))
{
attachmentValue = nodeNav.Value;
InfoPathAttachmentDecoder dec = new InfoPathAttachmentDecoder(attachmentValue);
string fileName = dec.Filename;
byte[] data = dec.DecodedAttachment;
itemDetail.Attachments.Add(fileName , data);
itemDetail.Update();
}
http://www.cnblogs.com/dexter2003/archive/2010/12/05/1887806.html
文件需满足一些条件才能被正确上传之MOSS中
- 判断文件是否为空,即文件内容什么都没有。
- 判断文件的扩展名是否存在。
- 判断文件名称是否包含特殊字符,参考http://support.microsoft.com/kb/894629 ( ~ # % & * { } | \ : " < > ? / )
- 判断文件扩展名称是否被禁用,在管理中心可设置。
- 判断文件上传大小,SharePoint 2010 默认是50M。