te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Posting ByteArray from Knockout.js to a Web Service - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Posting ByteArray from Knockout.js to a Web Service - Stack Overflow

programmeradmin2浏览0评论

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 munity can help! In my View I have the following data-binding on a file input:

 <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.

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

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:

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?

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

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.

Thanks in advance!

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 munity can help! In my View I have the following data-binding on a file input:

 <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.

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

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:

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?

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

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.

Thanks in advance!

Share Improve this question asked Aug 19, 2012 at 1:58 INNVTVINNVTV 3,3677 gold badges47 silver badges80 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

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-pliant 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./jsfiddle/knockout-fileapi (for some reason jsFiddle breaks badly for me when I try to run this code in it). Source code at Github.

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.

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.

More info: http://blogs.msdn./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"

发布评论

评论列表(0)

  1. 暂无评论