我正在开发一个Windows phone8应用程序,需要上传照片到亚马逊s3存储。但是,我发现这是不可能的,因为无论我使用什么超时设置,HttpClient都会在大约60秒后超时。
真的没有办法从Windows Phone上传大文件吗?
BackgroundTransferRequest是无用的,因为它不能通过文件上传发送必要的元数据。
我使用以下代码(超时):
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(30);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, m_uploadUrl);
httpContent.Headers.Add("Keep-Alive", "true");
request.Content = httpContent; // 3-5 Mb file
response = await httpClient.SendAsync(request);
statusCode = response.StatusCode;
}我也尝试了PostAsync(),但结果相同。大约60秒后,调用结束,状态码为400或404。这不是服务器超时。IPhone和安卓应用程序使用相同的服务。这没什么问题。
对于如何上传超过60秒才能发送的文件有什么建议吗?
发布于 2014-05-07 15:23:57
我也遇到过类似的事情。超时故障。检查是否可以使用另一个类来代替HttpClient。WebClient可能就是。
检查这是否对您有帮助:http://blog.anthonybaker.me/2013/06/how-to-upload-file-from-windows-phone.html
甚至还有这个:http://chriskoenig.net/2011/08/19/upload-files-from-windows-phone/
有了这些,我的事情就好办了。
发布于 2014-05-19 01:34:51
我现在已经用了几天的时间来实现一个新的上传程序,并让所有的细节都工作起来。我将HttpWebRequest与异步方法结合使用,并将文件拆分成块。最后,我让它正常工作,它在没有超时的情况下上传。下面是完整的代码:
using System;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Services
{
public class UploadData
{
public Stream PostStream { get; set; }
public Stream FileStream { get; set; }
public byte[] HeaderBytes {get; set;}
public byte[] FooterBytes {get; set;}
public byte[] Buffer { get; set; }
public Photo Upload { get; set; }
public int BytesWritten { get; set; }
}
public class UploadEventArgs : EventArgs
{
public Photo Upload { get; set; }
public int Progress { get; set; }
}
public class UploadService
{
public delegate void CompletedEventHandler(object sender, UploadEventArgs e);
public event CompletedEventHandler UploadCompleted;
public delegate void ProgressEventHandler(object sender, UploadEventArgs e);
public event ProgressEventHandler ProgressChanged;
private static string contentType = "multipart/form-data; boundary={0}";
private static string headerString = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\nContent-Type: Content-Type: application/octet-stream\r\n\r\n";
private HttpWebRequest m_request;
private static string boundarystr;
private UploadData m_uploadData;
private bool m_isStopped;
public async Task StartUpload(Photo upload, Uri uri, Dictionary<string, string> parameters)
{
try
{
m_isStopped = false;
var fileStream = (await upload.File.OpenReadAsync()).AsStreamForRead();
var uploadData = new UploadData();
boundarystr = "---------------------------" + DateTime.Now.Ticks.ToString("x");
string para = GetParamsString(parameters);
string headAndParams = para + String.Format(headerString, HttpUtility.UrlEncode(upload.File.Name));
var headerBytes = System.Text.Encoding.UTF8.GetBytes(headAndParams);
var footerBytes = Encoding.UTF8.GetBytes("\r\n--" + boundarystr + "--\r\n");
uploadData.Upload = upload;
uploadData.FileStream = fileStream;
uploadData.FooterBytes = footerBytes;
uploadData.HeaderBytes = headerBytes;
uploadData.BytesWritten = 0;
m_uploadData = uploadData;
m_request = (HttpWebRequest)WebRequest.Create(uri);
m_request.Method = "POST";
m_request.AllowWriteStreamBuffering = false;
m_request.ContentType = string.Format(contentType, boundarystr);
m_request.ContentLength = fileStream.Length + headerBytes.Length + footerBytes.Length;
var asyncResult = m_request.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, uploadData); }, m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Start upload failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult, UploadData uploadData)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(uploadData.HeaderBytes, 0, uploadData.HeaderBytes.Length);
var args = new UploadEventArgs();
args.Upload = uploadData.Upload;
args.Progress = 1;
OnProgressChanged(args);
uploadData.PostStream = postStream;
WriteNextChunck(uploadData);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Header write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void WriteNextChunck(UploadData upload)
{
try
{
if ((upload.FileStream.Length - upload.BytesWritten) >= 16 * 1024)
{
upload.Buffer = new byte[16 * 1024];
}
else
{
// Last part
upload.Buffer = new byte[upload.FileStream.Length - upload.BytesWritten];
}
upload.FileStream.Read(upload.Buffer, 0, (int)upload.Buffer.Length);
upload.PostStream.BeginWrite(upload.Buffer, 0, upload.Buffer.Length, BeginWriteCallback, upload);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Buffer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
upload.FileStream.Close();
upload.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void BeginWriteCallback(IAsyncResult ar)
{
try
{
var upload = ar.AsyncState as UploadData;
upload.PostStream.EndWrite(ar);
upload.BytesWritten += upload.Buffer.Length;
var args = new UploadEventArgs();
args.Upload = upload.Upload;
args.Progress = (int)(((decimal)upload.BytesWritten / (decimal)upload.FileStream.Length) * 100);
OnProgressChanged(args);
if (m_isStopped)
{
upload.FileStream.Close();
upload.PostStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload stopped");
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
return;
}
// write next chunck
if (upload.BytesWritten < upload.FileStream.Length)
{
WriteNextChunck(upload);
}
if (upload.BytesWritten >= upload.FileStream.Length)
{
WriteFooter(upload);
}
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void WriteFooter(UploadData upload)
{
try
{
upload.PostStream.Write(upload.FooterBytes, 0, upload.FooterBytes.Length);
upload.PostStream.Close();
var asyncResult = m_request.BeginGetResponse(new AsyncCallback(GetResponseCallback), m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Footer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
m_uploadData.FileStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = response.StatusCode;
if (response.StatusCode == HttpStatusCode.NoContent)
{
m_uploadData.Upload.UploadInfo.Exception = null;
}
else
{
m_uploadData.Upload.UploadInfo.Exception = new Exception(responseString);
}
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
args.Progress = 100;
OnUploadComplete(args);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = ex;
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
OnUploadComplete(args);
}
}
private string GetParamsString(Dictionary<string, string> parameters)
{
bool needsCLRF = false;
string result = "";
foreach (var param in parameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
result += "\r\n";
needsCLRF = true;
string prm = string.Format("--{0}\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Disposition: form-data; name={1}\r\n\r\n{2}",
boundarystr,
param.Key,
param.Value);
result += prm;
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundarystr + "\r\n";
result += footer;
return result;
}
protected virtual void OnUploadComplete(UploadEventArgs e)
{
if (UploadCompleted != null)
UploadCompleted(this, e);
}
protected virtual void OnProgressChanged(UploadEventArgs e)
{
if (ProgressChanged != null)
ProgressChanged(this, e);
}
public void Stop()
{
m_isStopped = true;
}
}
}https://stackoverflow.com/questions/23502295
复制相似问题