9

http://valums.com/ajax-upload/から見つけたスクリプトを使用しようとしています

私のコントローラーは次のとおりです

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using MHNHub.Areas.ViewModels;
using MHNHub.Models;
using MHNHub.ViewModels;

namespace MHNHub.Areas.Admin.Controllers
{
    [Authorize(Roles = "Administrator")]
    public class ImageController : Controller
    {

        private MHNHubEntities _entities = new MHNHubEntities();

        //
        // GET: /Image/
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult ImageUploader()
        {
            var viewModel = new ImageViewModel()
            {
                Image = new Image()
            };

            return PartialView(viewModel);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ImageUploader(Image image)
        {
            try
            {
                _entities.Images.AddObject(image);
                _entities.SaveChanges();

                return RedirectToAction("Index", "Product");
            }
            catch (Exception ex)
            {
                var viewModel = new ImageViewModel()
                                {
                                    Image = image,
                                    HasError = true,
                                    ErrorMessage = ex.Message
                                };
                return PartialView(viewModel);

            }
        }

        private string _uploadsFolder = HostingEnvironment.MapPath("~/App_Data/Files");

        public Guid Upload(HttpPostedFileBase fileBase)
        {
            var identifier = Guid.NewGuid();
            fileBase.SaveAs(GetDiskLocation(identifier));
            return identifier;
        }

        private string GetDiskLocation(Guid identifier)
        {
            return Path.Combine(_uploadsFolder, identifier.ToString());
        }

    }

}

そして、私はこのような部分的なビューを持っています

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MHNHub.ViewModels.ImageViewModel>" %>

<script type="text/javascript">
    $(function () {
        $("#imagedialog").dialog({
            bgiframe: true,
            height: 170,
            width: 430,
            modal: true,
            autoOpen: false,
            resizable: true
        })
    });

    $(document).ready(function createUploader() {
        var uploader = new qq.FileUploader({
            element: document.getElementById('fileuploader'),
            action: '/Image/Upload/',
            name: 'name'
        });

    });

</script>    

<div id="imagedialog" title="Upload Image">

                <div id="fileuploader">

                </div>
                <h6>Drag and drop files supported in Firefox and Google Chrome with javascript enabled.</h6> 
                    <noscript>
                         <form action="/image/upload" enctype="multipart/form-data" method="post">
                            Select a file: <input type="file" name="photo" id="photo" />   

                            <input type="submit" value="Upload" name="submit"/>
                        </form>
                    </noscript>


</div>

<div class="editor-field">
    <img src="<%: Model.Image.FileName %>" />
    <%: Html.TextBoxFor(model => model.Image.FileName) %>
    <%: Html.ValidationMessageFor(model => model.Image.FileName)%>
    <a href="#" onclick="jQuery('#imagedialog').dialog('open'); return false">Upload Image</a>
</div>

マスター ページに fileuploader.js と fileuploader.css が適切にリンクされており、アップローダーが正しく表示され、アクションを呼び出すことさえできますが、HttpPostedFileBase が null であり、アップロード アクションが例外をスローします。私が何をすべきかについての洞察はありますか?

編集

だから私は XmlHttpRequest を送信することを firebug を使用して理解しました。アップロード アクションでこれを処理するにはどうすればよいですか?

4

1 に答える 1

9

multipart/form-dataコントローラアクションで空のパラメータを取得する理由は、このプラグインがサーバーにリクエストを送信しないためです。代わりに、application/octet-streamコンテンツタイプのリクエストヘッダーを送信し、ファイルのコンテンツをリクエストストリームに直接書き込み、?qqfileファイル名を含むURLにパラメーターを追加します。したがって、コントローラーでこれを取得する場合は、ストリームを直接読み取る必要があります。

[HttpPost]
public ActionResult Upload(string qqfile)
{
    using (var reader = new BinaryReader(Request.InputStream))
    {
        // This will contain the uploaded file data and the qqfile the name
        byte[] file = reader.ReadBytes((int)Request.InputStream.Length);
    }
    return View();
}

複数のファイルを選択した場合、プラグインはサーバーに複数のリクエストを送信するだけなので、これは機能します。

また、より大きなファイルを処理する場合int.MaxValueは、ファイル全体をメモリバッファーにロードするのではなく、要求ストリームからチャンクで読み取り、出力ストリームに直接書き込む必要があります。

using (var outputStream = File.Create(qqfile))
{
    const int chunkSize = 2 * 1024; // 2KB
    byte[] buffer = new byte[chunkSize];
    int bytesRead;
    while ((bytesRead = Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        outputStream.Write(buffer, 0, bytesRead);
    }
}

備考:createUploaderから関数名を削除してくださいdocument.ready。そこでは匿名関数である必要があります。$(function() { ... });すでにモーダルダイアログを設定する必要があるものとマージすることもできます。

于 2010-09-13T06:38:09.340 に答える