问题
我正在尝试创建一个ASP.NET Core(3.1)Web应用程序,该应用程序接受文件上传,然后将其分成块通过MS Graph API发送到Sharepoint。这里有一些其他帖子涉及类似的问题,但它们假设我已经掌握了一定程度的.NET知识,而我目前还没有。因此,我希望有人能帮助我拼凑一些东西。
配置Web服务器和应用程序以接受大文件
我已经完成以下操作,以允许IIS Express上传高达2GB的文件:
a)创建了一个包含以下代码的web.config文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="Home/UploadFile">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<security>
<requestFiltering>
<!--unit is bytes => 2GB-->
<requestLimits maxAllowedContentLength="2147483647" />
</requestFiltering>
</security>
</system.webServer>
</location>
</configuration>
B) 我在我的Startup.cs配置部分中有以下内容:
//Add support for uploading large files TODO: DO I NEED THIS?????
services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue; // Limit on individual form values
x.MultipartBodyLengthLimit = int.MaxValue; // Limit on form body size
x.MultipartHeadersLengthLimit = int.MaxValue; // Limit on form header size
});
services.Configure<IISServerOptions>(options =>
{
options.MaxRequestBodySize = int.MaxValue; //2GB
});
这是我的表单,让用户选择文件并提交:
@{
ViewData["Title"] = "Messages";
}
<h1>@ViewData["Title"]</h1>
<p></p>
<form id="uploadForm" action="UploadFile" method="post" enctype="multipart/form-data">
<dl>
<dt>
<label for="file">File</label>
</dt>
<dd>
<input id="file" type="file" name="file" />
</dd>
</dl>
<input class="btn" type="submit" value="Upload" />
<div style="margin-top:15px">
<output form="uploadForm" name="result"></output>
</div>
</form>
这是控制器的样子:
[HttpPost]
[RequestSizeLimit(2147483647)] //unit is bytes => 2GB
[RequestFormLimits(MultipartBodyLengthLimit = 2147483647)]
public async void UploadFile()
{
User currentUser = null;
currentUser = await _graphServiceClient.Me.Request().GetAsync();
//nothing have to do with the file has been written yet.
}
当用户点击文件按钮并选择一个大文件时,我不再收到IIS 413错误消息。太好了。逻辑会命中我的控制器中的正确方法。
但是对于代码的这一部分,我有以下问题:
当用户选择文件时...实际上在幕后发生了什么?文件是否已经被插入到我的表单中,并且可以从我的控制器中访问?
它是一个流吗?
我该如何访问这个文件?
如果最终需要使用 this type 的方法将此文件发送到Sharepoint(分块的最后一个示例),似乎最好的方法是将文件保存在服务器上的某个位置...然后复制示例代码并尝试对其进行分块处理?示例代码似乎在引用文件路径和文件大小,我假设我需要先将其持久化到我的Web服务器上,然后再从那里开始。
如果我确实需要保存它,你能指点我正确的方向吗?也许有一些示例代码可以向我展示如何获取表单中POST的数据并将其保存?
最终,这将需要重构以便没有GUI...但它只是一个API,接受大文件上传到某个地方。但我想我会先学习如何以这种方式完成...然后重构以将我的代码更改为仅API。
抱歉提出这些初学者问题。在发帖之前,我已经尽力做了研究。但有些事情仍然有点模糊。
编辑1
根据发布的答案建议,我下载了演示代码,演示如何绕过保存到Web服务器本地文件的方法。它基于这篇文章。
我再次创建了一个web.config文件-以避免IIS的413错误。我还编辑了允许的文件扩展名列表,以支持.pdf和.docx和.mp4。
当我尝试运行示例项目,并选择“物理存储上传示例”部分下的“使用AJAX将文件流式传输到控制器端点”时,它就会停在这里:
// This check assumes that there's a file
// present without form data. If form data
// is present, this method immediately fails
// and returns the model error.
if (!MultipartRequestHelper
.HasFileContentDisposition(contentDisposition))
if (!MultipartRequestHelper
.HasFileContentDisposition(contentDisposition))
{
ModelState.AddModelError("File",
$"The request couldn't be processed (Error 2).");
// Log error
return BadRequest(ModelState);
}
正如在代码上方的评论中提到的那样,它正在检查表单数据,然后当它找到它时...它就停止了。因此,我一直在玩弄HTML页面,它看起来像这样:
<form id="uploadForm" action="Streaming/UploadPhysical" method="post"
enctype="multipart/form-data" onsubmit="AJAXSubmit(this);return false;">
<dl>
<dt>
<label for="file">File</label>
</dt>
<dd>
<input id="file" type="file" name="file" />asdfasdf
</dd>
</dl>
<input class="btn" type="submit" value="Upload" />
<div style="margin-top:15px">
<output form="uploadForm" name="result"></output>
</div>
</form>
而我已尝试像这样删除表单:
<dl>
<dt>
<label for="file">File</label>
</dt>
<dd>
<input id="file" type="file" name="file" />
</dd>
</dl>
<input class="btn" type="button" asp-controller="Streaming" asp-action="UploadPhysical" value="Upload" />
<div style="margin-top:15px">
<output form="uploadForm" name="result"></output>
</div>
但是当我点击按钮时,它现在没有任何作用。
另外,如果你想知道/有帮助的话,我手动复制了一个文件到我的电脑c:\files文件夹中,当示例应用程序打开时,它确实列出了该文件-证明它可以读取该文件夹。我添加了读/写权限,所以希望Web应用程序在我完成后能够写入它。