ここ Stackoverflow で見つけたメソッドをカスタマイズして、1 つの XML ファイルと複数の画像のマルチパート アップロードを有効にし、Sharepoint WebPart から HTTPWebRequest を処理しました。残念なことに、私は HttpRequest と StreamUpload のことをよく知らないと言わざるを得ません。これを真剣に処理しようとするのは初めてです。
これが私のコーディングです:
public XmlDocument DoHttpUploadFile(string url, string[] file, string[] paramName, string[] contentType, NameValueCollection nvc, NameValueCollection headerItems, string xmlFileName)
{
var xmlDox = new XmlDocument();
var totalLength = 0;
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
const string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
// First Loop is just need to get the Length of all Parts
for (int i = 0; i < file.Length; i++)
{
string header = "";
if (i == 0)
{
header = string.Format(headerTemplate, paramName[i], xmlFileName, contentType[i]);
}
else
{
var filename = Path.GetFileName(file[i]);
header = string.Format(headerTemplate, paramName[i], filename, contentType[i]);
}
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
var headerLength = headerbytes.Length;
var boundaryLength = boundarybytes.Length;
totalLength = totalLength + headerLength + boundaryLength;
if (file[i].StartsWith("<"))
{
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(file[i]);
var xmlLength = xmlBytes.Length;
totalLength = totalLength + xmlLength;
}
else
{
var client = new WebClient();
var img = new Image { ImageUrl = file[i] };
client.UseDefaultCredentials = true;
// image as Byte into Stream
var fileData = client.DownloadData(img.ImageUrl);
var imgLength = fileData.Length;
totalLength = totalLength + imgLength;
}
}
var wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.ContentLength = totalLength;
Stream rs = wr.GetRequestStream();
var read = 0;
var finalLength = 0;
for (int i = 0; i < file.Length; i++)
{
string header = "";
if(i==0)
{
header = string.Format(headerTemplate, paramName[i], xmlFileName, contentType[i]);
}
else
{
var filename = Path.GetFileName(file[i]);
header = string.Format(headerTemplate, paramName[i], filename, contentType[i]);
}
rs.Write(boundarybytes, 0, boundarybytes.Length);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
var headerLength = headerbytes.Length;
var boundaryLength = boundarybytes.Length;
finalLength = finalLength + headerLength + boundaryLength;
rs.Write(headerbytes, 0, headerbytes.Length);
if(file[i].StartsWith("<"))
{
var writer = new StreamWriter(rs);
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(file[i]);
var xmlLength = xmlBytes.Length;
finalLength = finalLength + xmlLength;
writer.Write(file[i]);
}
else
{
var getitem = new GetItemFromList();
var client = new WebClient();
var img = new Image {ImageUrl = file[i]};
client.UseDefaultCredentials = true;
// image as Byte into Stream
var fileData = client.DownloadData(img.ImageUrl);
finalLength = finalLength + fileData.Length;
rs.Write(fileData, 0, fileData.Length);
}
}
finalLength.ToString();
rs.Close(); // Here it stops with Exception 'Bytes are not completely written
WebResponse wresp = null;
try
{
wresp = wr.GetResponse();
var wrlength = wr.ContentLength;
var stream2 = wresp.GetResponseStream();
if (stream2 != null)
{
var reader2 = new StreamReader(stream2);
var backstr = reader2.ReadToEnd();
xmlDox.LoadXml(backstr);
}
}
catch (Exception ex)
{
//log.Error("Error uploading file", ex);
if (wresp != null)
wresp.Close();
wresp = null;
}
finally
{
wr = null; }
return xmlDox;
}
rs.Close で停止し、'Cannot Close Stream bytes are not writen complete' という例外が発生します。
コーディングの上記のセクションでわかるように、これはおそらく wr.ContentLength に依存していると思い、これを手動で設定しようとしました。
過去2日間試した解決策が見つからず、Web全体、特にstackeOverflowを検索しました。
それで、誰かが何がうまくいかないのか教えてくれるなら、教えてください、thx.