【问题标题】:Posting ByteArray from Knockout.js to a Web Service将 ByteArray 从 Knockout.js 发布到 Web 服务
【发布时间】:2012-08-14 22:57:33
【问题描述】:

我对 KnockoutJS 很陌生,到目前为止我一直在研究它,但尽我所能,我在任何地方都找不到此信息,所以我希望社区可以提供帮助!在我看来,我在文件输入上有以下数据绑定:

 <input type="file" data-bind="value: ImageToUpload"/>
 <button data-bind="click: $root.saveImage">Upload</button>

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

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

self.saveImage = function (MyObject, event) {

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

    });
}

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

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

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

3) 我的技术完全失效了吗?有一个更好的方法吗?我的目标是有一个上传到的图像“插槽”的动态列表。

提前致谢!

【问题讨论】:

    标签: javascript jquery asp.net post knockout.js


    【解决方案1】:

    无法访问本地文件内容是 JavaScript 安全沙箱的基本限制。随着HTML5 file API 的引入,它被取消了,但不幸的是,支持是far from universal。如果您的代码需要在不兼容的浏览器中工作,您唯一的选择是让浏览器处理传统的multipart/form-data 上传。另一方面,如果不支持 IE http://khayrov.github.com/jsfiddle/knockout-fileapi(由于某种原因,jsFiddle 在我尝试在其中运行这段代码时对我来说很糟糕)。 Source code 在 Github。

    【讨论】:

    • 我知道这已经过时了,但如果你还在,我有一个问题。如何将此数组缓冲区传递回 mvc 控制器?
    【解决方案2】:

    需要以特殊方式处理文件上传。它们通常不属于您的模型。看看下面的 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;
        }
    }
    

    另一种对代码不那么繁重的解决方案是使用 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.aspx 和 ASP.NET Web API File saved as "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af"

    【讨论】:

      猜你喜欢
      • 2015-07-28
      • 2011-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多