file - 如何获取上传到服务器的数据百分比
问题描述
我有一个包含以下参数的模型
public class FileExchangeDetails
{
public Guid SenderId { get; set; }
public List<Files> Files { get; set; }
public Guid Id { get; set; }
}
public class Files
{
public string FilePath { get; set; }
public string FileName { get; set; }
public byte[] FileBytes { get; set; }
public string FileType { get; set; }
}
我正在FileExchangeDetails
使用以下发送文件数据(图像或文件)
public static async Task<string> PostFilesToToApi(string apiUrl, FileExchangeDetails exchangeDetails)
{
try
{
using (var httpreqclient = new httpclient())
{
httpreqclient.baseaddress = new uri(string.format(apiurls.weburl, application.current.properties["currentsitename"]));
httpreqclient.defaultrequestheaders.add("authorization", "bearer " + applicationcontext.accesstoken);
httpreqclient.defaultrequestheaders.accept.add(new mediatypewithqualityheadervalue("application/json"));//accept header
var content = jsonconvert.serializeobject(exchangedetails, formatting.none);
var stringcontentinput = new stringcontent(content, encoding.utf8, "application/json");
var response = await httpreqclient.postasync(new uri(string.format(apiurls.weburl, application.current.properties["currentsitename"]) + apiurl), stringcontentinput);
var stringasync = await response.content.readasstringasync();
if (response.issuccessstatuscode)
{
var responsejson = stringasync;
return responsejson;
}
}
}
catch (Exception exception)
{
LoggingManager.Error(exception, "PostFilesToToApi", "ApiWrapper");
}
return null;
}
功能上一切正常,但现在我需要在上传到服务器时显示文件上传的百分比。
我对 Web 客户端的指导方针很少,但参数只有字节 [] 或字符串。
如何使用 httpclient 获取该百分比数据。有人可以帮我解决这个问题。
解决方案
您可以创建一个自定义HttpContent如下
internal class ProgressableStreamContent : HttpContent
{
private const int defaultBufferSize = 4096;
private Stream content;
private int bufferSize;
private bool contentConsumed;
private Download downloader;
public ProgressableStreamContent(Stream content, Download downloader) : this(content, defaultBufferSize, downloader) {}
public ProgressableStreamContent(Stream content, int bufferSize, Download downloader)
{
if(content == null)
{
throw new ArgumentNullException("content");
}
if(bufferSize <= 0)
{
throw new ArgumentOutOfRangeException("bufferSize");
}
this.content = content;
this.bufferSize = bufferSize;
this.downloader = downloader;
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Contract.Assert(stream != null);
PrepareContent();
return Task.Run(() =>
{
var buffer = new Byte[this.bufferSize];
var size = content.Length;
var uploaded = 0;
downloader.ChangeState(DownloadState.PendingUpload);
using(content) while(true)
{
var length = content.Read(buffer, 0, buffer.Length);
if(length <= 0) break;
downloader.Uploaded = uploaded += length;
stream.Write(buffer, 0, length);
downloader.ChangeState(DownloadState.Uploading);
}
downloader.ChangeState(DownloadState.PendingResponse);
});
}
protected override bool TryComputeLength(out long length)
{
length = content.Length;
return true;
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
content.Dispose();
}
base.Dispose(disposing);
}
private void PrepareContent()
{
if(contentConsumed)
{
// If the content needs to be written to a target stream a 2nd time, then the stream must support
// seeking (e.g. a FileStream), otherwise the stream can't be copied a second time to a target
// stream (e.g. a NetworkStream).
if(content.CanSeek)
{
content.Position = 0;
}
else
{
throw new InvalidOperationException("SR.net_http_content_stream_already_read");
}
}
contentConsumed = true;
}
}
推荐阅读
- python - 如何迭代字典中一个键的值列表
- unity3d - 如何在tilemap中动态设置tile?
- javascript - 如何使画布宽度和高度适合Vuetify中的父元素?
- java - 在 fxml 加载后获取节点的子节点
- bash - For循环 - 复制多个文件并在不同的目录中重命名扩展名
- spring-boot - docker 容器中的 H2 DB
- javascript - 使用 Azure 函数的动态输出 blob 路径
- jquery - 考虑到 thead 和 tbody 添加具有 td 索引的行
- javascript - 为什么Javascript构造函数不返回
- hashicorp-vault - Hashicorp Vault 令牌看起来不像 UUID