上传文件到服务
Upload files to service
我正在尝试调整 Kaltura API 以便它可以与 Windows 8.1 应用程序一起使用,但我在使用此功能时遇到问题:
private void PostMultiPartWithFiles(HttpWebRequest request, KalturaParams kparams, KalturaFiles kfiles)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
request.ContentType = "multipart/form-data; boundary=" + boundary;
// use a memory stream because we don't know the content length of the request when we have multiple files
MemoryStream memStream = new MemoryStream();
byte[] buffer;
int bytesRead = 0;
StringBuilder sb = new StringBuilder();
sb.Append("--" + boundary + "\r\n");
foreach (KeyValuePair<string, string> param in kparams)
{
sb.Append("Content-Disposition: form-data; name=\"" + param.Key + "\"" + "\r\n");
sb.Append("\r\n");
sb.Append(param.Value);
sb.Append("\r\n--" + boundary + "\r\n");
}
buffer = Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer, 0, buffer.Length);
foreach (KeyValuePair<string, FileStream> file in kfiles)
{
sb = new StringBuilder();
FileStream fileStream = file.Value;
sb.Append("Content-Disposition: form-data; name=\"" + file.Key + "\"; filename=\"" + Path.GetFileName(fileStream.Name) + "\"" + "\r\n");
sb.Append("Content-Type: application/octet-stream" + "\r\n");
sb.Append("\r\n");
// write the current string builder content
buffer = Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer, 0, buffer.Length);
// write the file content
buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
memStream.Write(buffer, 0, bytesRead);
buffer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
memStream.Write(buffer, 0, buffer.Length);
}
request.ContentLength = memStream.Length;
Stream requestStream = request.GetRequestStream();
// write the memorty stream to the request stream
memStream.Seek(0, SeekOrigin.Begin);
buffer = new Byte[checked((uint)Math.Min(4096, (int)memStream.Length))];
bytesRead = 0;
while ((bytesRead = memStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
requestStream.Close();
memStream.Close();
}
我试过这样的方法:
private void PostMultiPartWithFiles(HttpWebRequest request, KalturaParams kparams, KalturaFiles kfiles)
{
using (request)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
MultipartFormDataContent content = new MultipartFormDataContent(boundary);
foreach (KeyValuePair<string, string> param in kparams)
{
Stream fileStream = await new StringContent(param.Value).ReadAsStreamAsync();
StreamContent streamContent = new StreamContent(fileStream);
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"" + param.Key + "\"");
content.Add(streamContent);
}
foreach (var file in kfiles)
{
StorageFile storageFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(file.Value.Path);
var randomAccessStream = await storageFile.OpenReadAsync();
Stream stream = randomAccessStream.AsStreamForRead();
StreamContent streamContent = new StreamContent(stream);
content.Headers.Add("Content-Disposition", "form-data; name=\"" + file.Key + "\"; filename=\"" + file.Value.Name + "\"");
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Add(streamContent, "fileData", file.Value.Path);
}
}
}
但它不起作用。它说 fileData
没有附加。我以前没有真正使用过那些 web 东西,所以也许我做错了。
所以我终于知道怎么做了。我的代码如下所示:
byte[] concatinated = null;
string boundary = string.Empty;
boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] buffer;
StringBuilder sb = new StringBuilder();
sb.Append("--" + boundary + "\r\n");
foreach (KeyValuePair<string, string> param1 in kparams)
{
sb.Append("Content-Disposition: form-data; name=\"" + param1.Key + "\"" + "\r\n");
sb.Append("\r\n");
sb.Append(param1.Value);
sb.Append("\r\n--" + boundary + "\r\n");
}
buffer = Encoding.UTF8.GetBytes(sb.ToString());
byte[] fileBytes = null;
byte[] filebytes2 = null;
foreach (KeyValuePair<string, StorageFile> file in kfiles)
{
StorageFile storageFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(file.Value.Path);
using (IRandomAccessStreamWithContentType stream = await storageFile.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (DataReader reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
filebytes2 = BuildByteArray("fileData", storageFile.Name, fileBytes, boundary);
concatinated = new byte[buffer.Length + filebytes2.Length];
System.Buffer.BlockCopy(buffer, 0, concatinated, 0, buffer.Length);
System.Buffer.BlockCopy(filebytes2, 0, concatinated, buffer.Length, filebytes2.Length);
buffer = new byte[concatinated.Length];
concatinated.CopyTo(buffer, 0);
}
和
private byte[] BuildByteArray(string name, string fileName, byte[] fileBytes, string boundary)
{
// Create multipart/form-data headers.
byte[] firstBytes = Encoding.UTF8.GetBytes(String.Format(
"--{0}\r\n" +
"Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n" +
"\r\n",
boundary,
name,
fileName));
byte[] lastBytes = Encoding.UTF8.GetBytes(String.Format(
"\r\n" +
"--{0}--\r\n",
boundary));
int contentLength = firstBytes.Length + fileBytes.Length + lastBytes.Length;
byte[] contentBytes = new byte[contentLength];
// Join the 3 arrays into 1.
Array.Copy(
firstBytes,
0,
contentBytes,
0,
firstBytes.Length);
Array.Copy(
fileBytes,
0,
contentBytes,
firstBytes.Length,
fileBytes.Length);
Array.Copy(
lastBytes,
0,
contentBytes,
firstBytes.Length + fileBytes.Length,
lastBytes.Length);
return contentBytes;
}
然后我这样使用它:
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Content = new ByteArrayContent(concat);
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
requestMessage.Content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", boundary));
var response = await client.SendAsync(requestMessage);
var content = await response.Content.ReadAsStringAsync();
我从this article.
得到的想法和第二个功能
我正在尝试调整 Kaltura API 以便它可以与 Windows 8.1 应用程序一起使用,但我在使用此功能时遇到问题:
private void PostMultiPartWithFiles(HttpWebRequest request, KalturaParams kparams, KalturaFiles kfiles)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
request.ContentType = "multipart/form-data; boundary=" + boundary;
// use a memory stream because we don't know the content length of the request when we have multiple files
MemoryStream memStream = new MemoryStream();
byte[] buffer;
int bytesRead = 0;
StringBuilder sb = new StringBuilder();
sb.Append("--" + boundary + "\r\n");
foreach (KeyValuePair<string, string> param in kparams)
{
sb.Append("Content-Disposition: form-data; name=\"" + param.Key + "\"" + "\r\n");
sb.Append("\r\n");
sb.Append(param.Value);
sb.Append("\r\n--" + boundary + "\r\n");
}
buffer = Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer, 0, buffer.Length);
foreach (KeyValuePair<string, FileStream> file in kfiles)
{
sb = new StringBuilder();
FileStream fileStream = file.Value;
sb.Append("Content-Disposition: form-data; name=\"" + file.Key + "\"; filename=\"" + Path.GetFileName(fileStream.Name) + "\"" + "\r\n");
sb.Append("Content-Type: application/octet-stream" + "\r\n");
sb.Append("\r\n");
// write the current string builder content
buffer = Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer, 0, buffer.Length);
// write the file content
buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
memStream.Write(buffer, 0, bytesRead);
buffer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
memStream.Write(buffer, 0, buffer.Length);
}
request.ContentLength = memStream.Length;
Stream requestStream = request.GetRequestStream();
// write the memorty stream to the request stream
memStream.Seek(0, SeekOrigin.Begin);
buffer = new Byte[checked((uint)Math.Min(4096, (int)memStream.Length))];
bytesRead = 0;
while ((bytesRead = memStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
requestStream.Close();
memStream.Close();
}
我试过这样的方法:
private void PostMultiPartWithFiles(HttpWebRequest request, KalturaParams kparams, KalturaFiles kfiles)
{
using (request)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
MultipartFormDataContent content = new MultipartFormDataContent(boundary);
foreach (KeyValuePair<string, string> param in kparams)
{
Stream fileStream = await new StringContent(param.Value).ReadAsStreamAsync();
StreamContent streamContent = new StreamContent(fileStream);
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"" + param.Key + "\"");
content.Add(streamContent);
}
foreach (var file in kfiles)
{
StorageFile storageFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(file.Value.Path);
var randomAccessStream = await storageFile.OpenReadAsync();
Stream stream = randomAccessStream.AsStreamForRead();
StreamContent streamContent = new StreamContent(stream);
content.Headers.Add("Content-Disposition", "form-data; name=\"" + file.Key + "\"; filename=\"" + file.Value.Name + "\"");
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Add(streamContent, "fileData", file.Value.Path);
}
}
}
但它不起作用。它说 fileData
没有附加。我以前没有真正使用过那些 web 东西,所以也许我做错了。
所以我终于知道怎么做了。我的代码如下所示:
byte[] concatinated = null;
string boundary = string.Empty;
boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] buffer;
StringBuilder sb = new StringBuilder();
sb.Append("--" + boundary + "\r\n");
foreach (KeyValuePair<string, string> param1 in kparams)
{
sb.Append("Content-Disposition: form-data; name=\"" + param1.Key + "\"" + "\r\n");
sb.Append("\r\n");
sb.Append(param1.Value);
sb.Append("\r\n--" + boundary + "\r\n");
}
buffer = Encoding.UTF8.GetBytes(sb.ToString());
byte[] fileBytes = null;
byte[] filebytes2 = null;
foreach (KeyValuePair<string, StorageFile> file in kfiles)
{
StorageFile storageFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(file.Value.Path);
using (IRandomAccessStreamWithContentType stream = await storageFile.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (DataReader reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
filebytes2 = BuildByteArray("fileData", storageFile.Name, fileBytes, boundary);
concatinated = new byte[buffer.Length + filebytes2.Length];
System.Buffer.BlockCopy(buffer, 0, concatinated, 0, buffer.Length);
System.Buffer.BlockCopy(filebytes2, 0, concatinated, buffer.Length, filebytes2.Length);
buffer = new byte[concatinated.Length];
concatinated.CopyTo(buffer, 0);
}
和
private byte[] BuildByteArray(string name, string fileName, byte[] fileBytes, string boundary)
{
// Create multipart/form-data headers.
byte[] firstBytes = Encoding.UTF8.GetBytes(String.Format(
"--{0}\r\n" +
"Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n" +
"\r\n",
boundary,
name,
fileName));
byte[] lastBytes = Encoding.UTF8.GetBytes(String.Format(
"\r\n" +
"--{0}--\r\n",
boundary));
int contentLength = firstBytes.Length + fileBytes.Length + lastBytes.Length;
byte[] contentBytes = new byte[contentLength];
// Join the 3 arrays into 1.
Array.Copy(
firstBytes,
0,
contentBytes,
0,
firstBytes.Length);
Array.Copy(
fileBytes,
0,
contentBytes,
firstBytes.Length,
fileBytes.Length);
Array.Copy(
lastBytes,
0,
contentBytes,
firstBytes.Length + fileBytes.Length,
lastBytes.Length);
return contentBytes;
}
然后我这样使用它:
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Content = new ByteArrayContent(concat);
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
requestMessage.Content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", boundary));
var response = await client.SendAsync(requestMessage);
var content = await response.Content.ReadAsStringAsync();
我从this article.
得到的想法和第二个功能