您必须将缓冲区传输到服务器而不仅仅是文件名,因为该文件存在于客户端上。
我在上一个 KO 项目中使用了 HTML5 FileReader
首先一个自定义绑定从 DOM 元素中读取文件
(function () {
ko.bindingHandlers.file = {
init: function (element, valueAccessor, allBindingsAccessor) {
ko.utils.registerEventHandler(element, "change", function () {
writeValueToProperty(valueAccessor(), allBindingsAccessor, "file", element.files[0]);
});
},
update: function (element, valueAccessor) {
if (ko.utils.unwrapObservable(valueAccessor()) == null) {
element.value = "";
}
}
};
var writeValueToProperty = function (property, allBindingsAccessor, key, value, checkIfDifferent) {
if (!property || !ko.isObservable(property)) {
var propWriters = allBindingsAccessor()['_ko_property_writers'];
if (propWriters && propWriters[key])
propWriters[key](value);
} else if (ko.isWriteableObservable(property) && (!checkIfDifferent || property.peek() !== value)) {
property(value);
}
};
} ());
FileReader 用法(特定于我如何在我的应用程序中使用它的代码)。仅检查 FileReader 部分。请注意,如果您有大文件,则需要流式传输
processFiles: function (viewModel, callback) {
var files = [];
ko.utils.arrayForEach(viewModel.files, function (file) {
if (file.fileUpload() == null) return;
var count = Enumerable.From(viewModel.files)
.Where(function(f) { return f.fileUpload() != null; })
.Count();
var reader = new FileReader();
reader.onload = function (e) {
var base64 = e.target.result.substr(e.target.result.indexOf(",") + 1);
files.push({ Type: file.type, Data: base64, Filename: file.fileUpload().name });
if (files.length == count) {
callback(files);
}
};
reader.readAsDataURL(file.fileUpload());
});
}
更新
就像说这是我的用例的代码,您需要更改它以适合您的目的
<div data-bind="foreach: files">
<p><label data-bind="text: typeName"></label><input data-bind="file: fileUpload" type="file" /></p>
</div>
控制器(如果我今天这样做,我会使用 WebApi)
public JsonResult UploadFiles(IEnumerable<FileUploadViewModel> uploads)
{
fileRepository.SaveUploadedFiles(Mapper.Map<IEnumerable<FileUploadViewModel>, IEnumerable <FileUpload>> (uploads));
return string.Empty.AsJson();
}
文件上传视图模型
public class FileUploadViewModel
{
public FileType Type { get; set; }
public string Filename { get; set; }
public string Data { get; set; }
}
自动映射器配置
Mapper.CreateMap<FileUploadViewModel, FileUpload>()
.ForMember(to => to.Buffer, opt => opt.MapFrom(from => Convert.FromBase64String(from.Data)));