1

我的 Web 应用程序需要将多个附件保存到我的 SQL 服务器。附件可以是任何格式。是否可以创建一个淘汰视图模型来将客户端的文件类型编码为二进制并将该二进制信息传输到我的 SQL 服务器?

我目前在我的 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;
        }

    }

我知道这是不正确的,但我真的不确定如何上传这个文件。我相信我把它复杂化了。任何协助将不胜感激。

4

1 回答 1

3

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

我在上一个 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)));
于 2013-08-07T07:56:09.497 回答