【问题标题】:Error when trying to send a 100mb byte array from js to c# using ajax尝试使用 ajax 将 100mb 字节数组从 js 发送到 c# 时出错
【发布时间】:2017-04-11 20:05:45
【问题描述】:

所以我已经做了几天了,我遇到了一个问题。我正在尝试进行 ajax 调用,将字节 [] 发送到 c# 中的控制器。

var data = { FtpUpload: self.Upload(), Attachment: self.Attachment() };
Base.ServiceCall("/Home/Upload", "post", data, true, function  (response) {...}

self.Attachment() 包含 'byte[]' 的属性。我使用它从按计划工作的文件中读取字节数组。

self.OnImageUpload = function (vm, evt) {
  var file = evt.target.files[0];
  var reader = new FileReader();

  reader.onload = function () {
    var attachment = {
      ...
      Attachment: reader.result.split(',')[1]
    };
    self.Attachment(attachment);
  }

  reader.readAsDataURL(file);
};

当我使用 17mb 文件执行此操作时,它可以正常工作,但是当我使用 109mb 文件执行此操作时,它会抛出一个 500 错误,说明这一点。

[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
   System.Web.Util.HttpEncoder.UrlDecode(Byte[] bytes, Int32 offset, Int32 count, Encoding encoding) +76
   System.Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding encoding) +164
   System.Web.HttpRequest.FillInFormCollection() +77

[HttpException (0x80004005): The URL-encoded form data is not valid.]
   System.Web.HttpRequest.FillInFormCollection() +130
   System.Web.HttpRequest.EnsureForm() +69
   System.Web.HttpRequest.get_Form() +13
   System.Web.HttpRequestWrapper.get_Form() +14

我已将适当的设置添加到我的 web.config 以允许像这样的更大文件。

<system.web>  
  <httpRuntime targetFramework="4.6" maxRequestLength="2147483647" executionTimeout="1600" requestLengthDiskThreshold="2147483647" />
</system.web>

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="2147483647" />
    </requestFiltering>
  </security>
</system.webServer>

我不知道还能做什么。

【问题讨论】:

  • 由于您遇到内存不足异常,我怀疑这不是您的配置问题。您可以发布接收数据的网站方法吗?我怀疑问题就在那里。因为您收到错误 500,这意味着它发生在服务器上,因此引发此异常的不是您的 JavaScript。
  • 如果你想要一个字节数组,你应该考虑使用reader.readAsArrayBuffer()readAsDataURL 将对您的文件进行 base64 编码,这会大大增加数据的大小。
  • "如果你想要一个字节数组,你应该考虑使用 reader.readAsArrayBuffer()。"我试过了,但是字节数组在后端是空的。我试图将数组缓冲区传递给字节 []。我需要先把它转换成任何东西吗?

标签: javascript c# ajax asp.net-mvc


【解决方案1】:

根据堆栈跟踪,您的调用在 HttpEncoder.UrlDecode 内失败,这只有在您将图像发送为 application/x-www-form-urlencoded 时才有可能,这在您处理大量二进制数据时可能是也可能不是最佳选择。

无论您选择使用哪种内容类型,您都必须使用HttpPostedFileBase 参数重新实现您的发布操作,该参数为您提供InputStream.Read 方法,而不是从请求表单中期待byte[],见下文.

[HttpPost]
public JsonResult Upload(HttpPostedFileBase uploadedFile)
...
byte[] fileByteArray = new byte[uploadedFile.ContentLength];
uploadedFile.InputStream.Read(fileByteArray, 0, uploadedFile.ContentLength);
...

您可以在示例中看到操作参数必须为 HttpPostedFileBase 才能流式传输文件,而不是作为整个二进制数据数组发送/接收。

看看下面的项目 https://www.codeproject.com/Articles/1021004/Upload-File-Using-Ajax-And-HTML-in-MVC

【讨论】:

  • 我试过了,还是不行。无论如何,谢谢。
  • 在这种情况下,您应该得到另一个异常堆栈跟踪。你能查一下吗?
  • [OutOfMemoryException: 'System.OutOfMemoryException' 类型的异常被抛出。] System.Web.Util.HttpEncoder.UrlDecode(Byte[] bytes, Int32 offset, Int32 count, Encoding encoding) +76 System .Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding encoding) +164 System.Web.HttpRequest.FillInFormCollection() +77
  • [HttpException (0x80004005): URL 编码的表单数据无效。] System.Web.HttpRequest.FillInFormCollection() +130 System.Web.HttpRequest.EnsureForm() +69 System.Web .HttpRequest.get_Form() +13 System.Web.HttpRequestWrapper.get_Form() +14 System.Web.Mvc.HttpRequestExtensions.GetHttpMethodOverride(HttpRequestBase 请求) +121 System.Web.Mvc.AcceptVerbsAttribute.IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) +37
  • 嗯,奇怪,堆栈跟踪是相同的,这意味着您仍然使用“application/x-www-form-urlencoded”发布。您可能需要检查 Fiddler 中的请求标头以进行仔细检查。
猜你喜欢
  • 2017-09-05
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
相关资源
最近更新 更多