组件
- 在 asp.net web 表单上有一些值的表单
- 文件输入(标准 HTML5,不是 asp:File 或类似的东西)
- 我理解的 bluimp jQuery 文件上传器非常适合这类事情,但从未使用过
- 一个 MVC4 WebAPI 控制器
- Web 表单的 JavaScript 中的 knockoutJS 视图模型(在这里不重要,但值得一提)。
目标
基本上,我上传了很小的 Excel 表格,用于验证、处理、转换为业务对象并作为 JSON 项返回。
我希望发生以下情况:
- 用户在表单中输入一些数据等。
- 用户将文件添加到表单。
- 该文件与包含文本的表单字段值一起自动上传(使用 bluimp 控件)到 MVC 控制器。
接下来,在控制器上,
- 传入的文本字段经过清理/验证。
- 文件被处理到内存中
- (这些真的很小,而且数量不多,所以我认为我们不需要去文件系统?)
- 然后使用使用流的 a 处理该文件
FileProcessor
,并使用文本字段进行实例化。
问题
我对这些组件的理解还不够好,无法理解我是在犯一个简单的错误还是一个复杂的错误。
到目前为止我所拥有的
注意:正在尝试使用按钮显式单击以发送文件,但将来我想自动执行此操作。
提交文件的表格:
<form id="fileUploadForm" action="/api/InvoiceDetailsFile/PostForProcessing" method="POST" enctype="multipart/form-data">
<input type ="hidden" name="clientSiteId" id="clientSiteId" value="3"/>
<input type="file" id="inpFile" required="required"/>
<input type ="button" id="btnSendFile" title="Send File" value="Send File"/>
</form>
上传的 JavaScript(这可能非常错误):
$(document).ready(function () {
'use strict';
var btnSendFile = $("#btnSendFile");
var frmFileUpload = $("#fileUploadForm");
btnSendFile.click(function () {
console.log('send button clicked');
frmFileUpload.fileupload("send");
});
});
处理上传的 WebAPI 控制器(这可能是非常错误的):
[HttpPost]
public Task<List<IInvoiceDetailItem>> PostForProcessing(int clientSiteId)
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var results = new List<IInvoiceDetailItem>();
var streamProvider = new MultipartMemoryStreamProvider();
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
// can I only expect 1 item here?
foreach (var item in streamProvider.Contents)
{
// if it's an Excel Sheet
if (item.IsMimeMultipartContent("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
{
try {
var workbook = new XLWorkbook(item.ReadAsStreamAsync().Result);
// clientSiteId here comes from form value (via constructor?), ContextUser comes from a BaseApi.
var processor =
new InvoiceProcessorFactory(clientSiteId, ContextUser)
.GetInvoiceProcessorInstance();
results = processor.ProcessInvoice(workbook).ToList();
}
catch (Exception ex)
{
throw new HttpException(Convert.ToInt32(HttpStatusCode.InternalServerError), "Well, this is a bummer. The invoice processor failed. Please see the inner exception.", ex);
}
}
}
return results;
});
return task;
}
随着我的进步,我会继续更新代码示例,但我想早点把它拿出来,因为我知道我会为此苦苦挣扎。