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

时间:2022-12-03 12:53:58

I'm very new to KnockoutJS, and I dig it so far, but try as I might I couldn't find this info anywhere so I am hoping the community can help! In my View I have the following data-binding on a file input:

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

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

This is part of a list in a "foreach" div, so the variable "ImageToUpload" corresponds to a property on an object from that list.

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

In my ViewModel the Upload button calls saveImage() and I call the web service and pass the form data to a .aspx page:

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

self.saveImage = function (MyObject, event) {

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

    });
}

The object passes to my service just fine and I can access all the form data as expected including the "ImageToUpload" variable... but here is where I am stuck:

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

1) The "ImageToUpload" is only a string representing the name of the file I uploaded and is not a ByteArray. How do I access the image file and not just the name?

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

2) Is there a better way to pass the ByteArray as a Stream or other format in the response header?

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

3) Is my technique totally off? Is there a better way to do this? My goal is to have a dynamic list of image "slots" that be uploaded to.

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

Thanks in advance!

提前致谢!

2 个解决方案

#1


8  

Inability to access local file contents was a fundamental limitation of JavaScript security sandbox. It was lifted with the introduction of HTML5 file API, but, unfortunately, support is far from universal. If your code needs to work in non-compliant browsers, your only option is to let the browser handle the traditional multipart/form-data upload. If, on the other hand, not supporting IE < 10 is fine for you, it is possible to use File API "the Knockout way" with custom bindings. Have a look at this example: http://khayrov.github.com/jsfiddle/knockout-fileapi (for some reason jsFiddle breaks badly for me when I try to run this code in it). Source code at Github.

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

#2


6  

File uploads need to be handled in a special manner. They are generally not part of your model. Take a look at the following ApiController. Specialized classes such as the MultipartFormDataStreamProvider are used to access the binary data that was submitted to the controller.

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

An alternative solution that's a little less heavy on the code is to use HttpPostedFileBase as a parameter for your ApiController. HttpPostedFileBase is essentially a wrapper for a file that was uploaded through a form. I must add that using MultipartFormDataStreamProvider is preferred over HttpPostedFileBase, because the latter is part of the ASP.NET MVC framework. Remember, WebAPI technology can be used outside of ASP.NET MVC.

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

More info: http://blogs.msdn.com/b/henrikn/archive/2012/03/01/file-upload-and-asp-net-web-api.aspx and ASP.NET Web API File saved as "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af"

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

#1


8  

Inability to access local file contents was a fundamental limitation of JavaScript security sandbox. It was lifted with the introduction of HTML5 file API, but, unfortunately, support is far from universal. If your code needs to work in non-compliant browsers, your only option is to let the browser handle the traditional multipart/form-data upload. If, on the other hand, not supporting IE < 10 is fine for you, it is possible to use File API "the Knockout way" with custom bindings. Have a look at this example: http://khayrov.github.com/jsfiddle/knockout-fileapi (for some reason jsFiddle breaks badly for me when I try to run this code in it). Source code at Github.

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

#2


6  

File uploads need to be handled in a special manner. They are generally not part of your model. Take a look at the following ApiController. Specialized classes such as the MultipartFormDataStreamProvider are used to access the binary data that was submitted to the controller.

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

An alternative solution that's a little less heavy on the code is to use HttpPostedFileBase as a parameter for your ApiController. HttpPostedFileBase is essentially a wrapper for a file that was uploaded through a form. I must add that using MultipartFormDataStreamProvider is preferred over HttpPostedFileBase, because the latter is part of the ASP.NET MVC framework. Remember, WebAPI technology can be used outside of ASP.NET MVC.

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

More info: http://blogs.msdn.com/b/henrikn/archive/2012/03/01/file-upload-and-asp-net-web-api.aspx and ASP.NET Web API File saved as "BodyPart_3ded2bfb-40be-4183-b789-9301f93e90af"

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