我在上传太大的文件时试图捕获错误。
在服务器上,多部分读取器抛出了我捕获并作为BadRequest返回的内容(也尝试了InternalError):
try
{
var section = await reader.ReadNextSectionAsync();
while (section != null)
{
...
}
}
catch (Exception ex)
{
return StatusCode((int)HttpStatusCode.BadRequest, ProblemFactory.Shared.BadRequestProblem("Could not upload file", ex.Message));
}
要上传,我有以下内容(当前使用RestSharp,但通过HttpClientFactory与HttpClient取得相同的结果):
var request = new RestRequest(REQ_UPLOADFILE, Method.POST, DataFormat.Json);
var token = await _agentTokenService.GetToken();
AddTokenHeader(request, token.AccessToken);
request.AddFile("file", path);
request.AddParameter("externalFileType", fileType, ParameterType.GetOrPost);
request.AddParameter("subType", subType, ParameterType.GetOrPost);
var resp = await _client.ExecuteTaskAsync(request);
if (resp.IsSuccessful)
{
return JsonConvert.DeserializeObject<ExternalFileResponse>(resp.Content);
}
else
{
string reason = "unknown error";
//switch(resp.StatusCode)
//{
// case HttpStatusCode.???
//}
throw new Exception($"Could not upload file: {reason}");
}
帖子的回复是状态码0,并显示一条消息:
该流不支持并发的IO读写操作
上载正在任务中运行,所以我想这与它有关,但是只有一个下载正在运行,如果文件较小,则可以正常工作。
我只能认为响应处理中的某些内容以某种方式不正常。
有人知道吗?
感谢和圣诞快乐:)
PS:我仅使用Kestrel-没有IIS或nginx-具有以下选项:
.UseKestrel(options =>
{
options.AddServerHeader = false;
options.Limits.MaxRequestBodySize = 100 * 1024 * 1024; // 100 MB
})
更新
我想我现在对此更好了。
从流中读取字节时,服务器正在终止连接。
客户端,异步写入,继续进行一小段时间,但是我尝试读取响应-因此出现错误消息。
更新 HttpClient的响应确实有所不同-我收到我的badrequest,消息是流已关闭。
答案 0 :(得分:-4)
这是使用ASP.NET加载大文件的简单方法。
(1)下载https://github.com/fex-team/webuploader上的webupload
(2)webupload可以将大文件上传到块文件,创建Web表单
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="../Javascript/jquery-1.9.1.min.js"></script>
<link href="../javascript/webuploader/webuploader.css" rel="stylesheet" />
<script src="../javascript/webuploader/webuploader.js"></script>
</head>
<body >
<form>
<br /><br />
<div id="uploader" class="wu-example">
<div class="btns">
<div id="picker" style="display:inline-block">Select a File</div>
<input id="ctlBtn" type="button" value="Upload" class="btn btn-primary" style="border-radius:0px; position:relative; top:-13px"/>
</div>
<div id="thelist" class="uploader-list"></div>
</div>
<script>
_extensions = '3gp,mp4,rmvb,mov,avi,m4v';
_mimeTypes = 'video/*,audio/*,application/*';
var GUID = WebUploader.Base.guid();//一个GUID
// alert(GUID);
uploader = WebUploader.create({
auto: false,
// swf path
swf: '../javascript/webuploader/Uploader.swf',
//server receive data
server: '_uploadVideo.aspx',
pick: {
id: '#picker',
label: 'Select a File',
innerHTML: 'Select a File',
multiple: false
},
fileNumLimit: 1,
fileSingleSizeLimit: 1024 * 1024 * 120,
accept: {
title: 'large file',
extensions: _extensions,
mimeTypes: _mimeTypes, // eg. image/*,
},
chunked: true,//split large into small file
chunkSize: 1024 * 1024 * 2, //every small file size,this is 2M
formData: {
guid: GUID,
types:"upload"
}
});
uploader.on('fileQueued', function (file) {
$("#thelist").append('<div id="' + file.id + '" class="item">' +
'<b class="info">' + file.name + '</b> ' +
'<p class="state">wait...</p>' + '</div>');
});
uploader.on('uploadSuccess', function (file, response) {
//merge small into a large file
$('#' + file.id).find('p.state').html('<font color=green>upload success</font>');
$.post('_uploadVideo.aspx', { guid: GUID, fileName: file.name, types: "merge" ,r:Math.random(),itemid:<%=Request.QueryString["itemid"]%> },
function (data) {
if (data == 1) {
alert("success");
}
else {
alert("fail");
}
});
});
uploader.on("error", function (type, handler) {
if (type == "Q_TYPE_DENIED") {
alert("format error");
} else if (type == "F_EXCEED_SIZE") {
alert("size too large");
}
});
uploader.on('uploadProgress', function (file, percentage) {
var $li = $('#' + file.id),
$percent = $li.find('.progress .progress-bar');
// stop re-upload
if (!$percent.length) {
$percent = $('<div class="progress progress-striped active">' +
'<div class="progress-bar" role="progressbar" style="width: 0%">' +
'</div>' +
'</div>').appendTo($li).find('.progress-bar');
}
$li.find('p.state').text('uploading');
$percent.css('width', percentage * 100 + '%');
});
$("#ctlBtn").click(
function () {
uploader.upload();
}
);
</script>
</form>
</body>
</html>
(3)创建一个asp.net网络表单页面_uploadVideo.aspx 删除所有内容,aspx只能有1行
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="_uploadVideo.aspx.cs" Inherits="Gallery.Gallery._uploadVideo" %>
(4)如下代码_uploadVideo.aspx.cs中的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Data.SqlClient;
namespace Gallery.Gallery
{
public partial class _uploadVideo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request["types"] == "upload")
{
if (Request.Form.AllKeys.Any(m => m == "chunk"))
{
int year = DateTime.Now.Year;
//取得chunk和chunks
int chunk = Convert.ToInt32(Request["chunk"]);
int chunks = Convert.ToInt32(Request["chunks"]);
string folder = Server.MapPath("../uploads/video/"+year+"/" + Request["guid"] + "/");
string path = folder + chunk;
//建立临时传输文件夹 create teamplate folder
if (!Directory.Exists(Path.GetDirectoryName(folder)))
{
Directory.CreateDirectory(folder);
}
FileStream addFile = new FileStream(path, FileMode.Append, FileAccess.Write);
BinaryWriter AddWriter = new BinaryWriter(addFile);
//获得上传的分片数据流 get chunk
var file = Request.Files[0];
Stream stream = file.InputStream;
BinaryReader TempReader = new BinaryReader(stream);
//将上传的分片追加到临时文件末尾
AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
//关闭BinaryReader文件阅读器
TempReader.Close();
stream.Close();
AddWriter.Close();
addFile.Close();
TempReader.Dispose();
stream.Dispose();
AddWriter.Dispose();
addFile.Dispose();
string f_ext = Path.GetExtension(file.FileName);
string _result = "{\"chunked\" :\"true\",\"hasError\" :\"false\",\"f_ext\" :\"" + f_ext + "\" }";
System.Web.HttpContext.Current.Response.Write(_result);
}
}
if (Request["types"] == "merge")
{
try
{
int year = DateTime.Now.Year;
var guid = Request["guid"];//GUID
var uploadDir = Server.MapPath("../uploads/video/" + year+"/");//Upload 文件夹
//建立临时传输文件夹
if (!Directory.Exists(Path.GetDirectoryName(uploadDir)))
{
Directory.CreateDirectory(uploadDir);
}
var dir = Path.Combine(uploadDir, guid);//临时文件夹
var ext = Path.GetExtension(Request["fileName"]);
var files = Directory.GetFiles(dir);//获得下面的所有文件
var name = Guid.NewGuid().ToString("N") + ext;
var finalPath = Path.Combine(uploadDir, name);//最终的文件名
var fs = new FileStream(finalPath, FileMode.Create);
foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序,保证从0-N Write
{
var bytes = System.IO.File.ReadAllBytes(part);
fs.Write(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);//删除分块
}
fs.Flush();
fs.Close();
Directory.Delete(dir);//删除文件夹
//INSERT INTO DB finalPath
SqlParameter[] p = {
new SqlParameter("@videopath","../uploads/video/" + year+"/"+name)
};
string sql = @"update portal_photoes set videopath=@videopath where id=" + int.Parse(Request["itemid"]);
//you can exe SQL to into database
System.Web.HttpContext.Current.Response.Write("1");
}
catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write("0");
}
}
}
}
}