将Knockout.js中的ByteArray发布到Web服务

INN*_*VTV 7 javascript asp.net jquery post knockout.js

我是KnockoutJS的新手,到目前为止我都在挖掘它,但我可能会尝试在任何地方都找不到这些信息,所以我希望社区可以提供帮助!在我的视图中,我对文件输入有以下数据绑定:

 <input type="file" data-bind="value: ImageToUpload"/>
 <button data-bind="click: $root.saveImage">Upload</button>
Run Code Online (Sandbox Code Playgroud)

这是"foreach"div中列表的一部分,因此变量"ImageToUpload"对应于该列表中对象的属性.

在我的ViewModel中,Upload按钮调用saveImage(),我调用Web服务并将表单数据传递给.aspx页面:

self.saveImage = function (MyObject, event) {

    $.post("Service.aspx", MyObject,  function (returnedData) {

    });
}
Run Code Online (Sandbox Code Playgroud)

该对象传递给我的服务很好,我可以按预期访问所有表单数据,包括"ImageToUpload"变量......但这里是我被卡住的地方:

1)"ImageToUpload"只是一个字符串,表示我上传的文件的名称,而不是ByteArray.如何访问图像文件而不仅仅是名称?

2)是否有更好的方法将ByteArray作为Stream或其他格式传递给响应头?

3)我的技术完全没了?有一个更好的方法吗?我的目标是拥有一个上传到的图像"插槽"的动态列表.

提前致谢!

rkh*_*rov 8

无法访问本地文件内容是JavaScript安全沙箱的基本限制.它随着HTML5文件API的引入而被解除,但不幸的是,支持远非普遍.如果您的代码需要在不兼容的浏览器中运行,那么您唯一的选择就是让浏览器处理传统的multipart/form-data上传.另一方面,如果不支持IE <10,那么可以使用自定义绑定的File API"Knockout方式".看看这个例子:http://khayrov.github.com/jsfiddle/knockout-fileapi(出于某种原因,当我尝试在其中运行此代码时,jsFiddle对我来说非常糟糕).Github的源代码.


Mar*_*ers 6

文件上传需要以特殊方式处理.它们通常不属于您的模型.看看下面的ApiController.诸如之类的专用类MultipartFormDataStreamProvider用于访问提交给控制器的二进制数据.

public class FileUploadController : ApiController
{
    [HttpPost]
    public List<FileResult> UploadFile()
    {
        // Verify that this is an HTML Form file upload request
        if (!Request.Content.IsMimeMultipartContent("form-data"))
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        // Create a stream provider for setting up output streams
        MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider();

        // Read the MIME multipart content using the stream provider we just created.
        IEnumerable<HttpContent> bodyparts = Request.Content.ReadAsMultipartAsync(streamProvider).Result;

        // The submitter field is the entity with a Content-Disposition header field with a "name" parameter with value "submitter"
        string submitter;
        if (!bodyparts.TryGetFormFieldValue("submitter", out submitter))
        {
            submitter = "unknown";
        }

        // Get a dictionary of local file names from stream provider.
        // The filename parameters provided in Content-Disposition header fields are the keys.
        // The local file names where the files are stored are the values.
        IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames;

        // Create response containing information about the stored files.
        return bodyPartFileNames.Select(kv =>
        {
            FileInfo fileinfo = new FileInfo(kv.Value);
            return new FileResult
            {
                FileName = kv.Key,
                LocalPath = fileinfo.FullName,
                LastModifiedTime = fileinfo.LastWriteTimeUtc,
                Length = fileinfo.Length,
                Submitter = submitter
            };
        }).ToList();
    }

    private static bool TryGetFormFieldValue(IEnumerable<HttpContent> contents, string dispositionName, out string formFieldValue)
    {
        HttpContent content = contents.FirstDispositionNameOrDefault(dispositionName);
        if (content != null)
        {
            formFieldValue = content.ReadAsStringAsync().Result;
            return true;
        }

        formFieldValue = null;
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

对代码稍微不那么重的替代解决方案是HttpPostedFileBase用作ApiController的参数.HttpPostedFileBase本质上是通过表单上传的文件的包装器.我必须补充说,使用 MultipartFormDataStreamProvider是首选HttpPostedFileBase,因为后者是ASP.NET MVC框架的一部分.请记住,WebAPI技术可以在ASP.NET MVC之外使用.

更多信息:http://blogs.msdn.com/b/henrikn/archive/2012/03/01/file-upload-and-asp-net-web-api.aspxASP.NET Web API文件保存为" BodyPart_3ded2bfb-40BE-4183-b789-9301f93e90af"