上传文件到服务

时间:2016-04-05 09:04:37

标签: c# windows-8.1 multipartform-data kaltura

我正在尝试调整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没有附加。我之前没有真正使用过这些网络内容,所以也许我做错了。

1 个答案:

答案 0 :(得分:0)

所以我终于有了怎么做。我的代码如下所示:

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得到的想法和第二个功能。