File upload 使用knockout js将文件保存到SQL server

File upload 使用knockout js将文件保存到SQL server,file-upload,knockout.js,File Upload,Knockout.js,我的web应用程序要求将多个附件保存到SQL server。附件可以是任何格式。是否可以创建一个剔除视图模型,将客户端的文件类型编码为二进制,并将二进制信息传输到我的SQL server 我目前在REST服务中使用此方法: [OperationContract, WebInvoke(ResponseFormat = WebMessageFormat.Json)] public string PostAttachments (string FileName) {

我的web应用程序要求将多个附件保存到SQL server。附件可以是任何格式。是否可以创建一个剔除视图模型,将客户端的文件类型编码为二进制,并将二进制信息传输到我的SQL server

我目前在REST服务中使用此方法:

[OperationContract, WebInvoke(ResponseFormat = WebMessageFormat.Json)]
    public string PostAttachments (string  FileName)
    {
        try
        {
            var MyAttachment = new Binary(File.ReadAllBytes(FileName));
            return "Attachments Created";
        }
        catch (Exception ex)
        {

            return DefaultError + ex;
        }

    }

我知道这是不正确的,但我真的不知道如何做这个文件上传。我认为我把事情复杂化了。非常感谢您的帮助。

您必须将缓冲区传输到服务器,而不仅仅是文件名,因为文件存在于客户机上

我在上一个KO项目中使用了HTML5文件阅读器

首先是从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>
自动映射配置

Mapper.CreateMap<FileUploadViewModel, FileUpload>()
      .ForMember(to => to.Buffer, opt => opt.MapFrom(from => Convert.FromBase64String(from.Data)));
Mapper.CreateMap()
.ForMember(to=>to.Buffer,opt=>opt.MapFrom(from=>Convert.FromBase64String(from.Data));

能否提供HTML和LINQ to SQL代码,说明它的大致外观?我更新了更多代码。顺便说一句,文件类型是特定于域的,在这种情况下,它不是用Automapper配置更新的mimetype
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)));