ASP.NET MVCで動作するようにjQueryプラグイン ploadify を取得しようとしています。
次のJavaScriptスニペットでプラグインが正常に表示されます。
<script type="text/javascript">
$(document).ready(function() {
$('#fileUpload').fileUpload({
'uploader': '/Content/Flash/uploader.swf',
'script': '/Placement/Upload',
'folder': '/uploads',
'multi': 'true',
'buttonText': 'Browse',
'displayData': 'speed',
'simUploadLimit': 2,
'cancelImg': '/Content/Images/cancel.png'
});
});
</script>
すべてが順調に進んでいるようです。気付いた場合、「script」属性は私の/ Placement/Uploadに設定されています。これは私のPlacement Controllerと私のUpload Actionです。
主な問題は、ファイルを受信するためにこのアクションを起動するのが難しいことです。そのアクションにブレークポイントを設定しました。アップロードするファイルを選択すると、実行されません。
私はオフに基づいてメソッドシグネチャを変更しようとしました この記事 :
public string Upload(HttpPostedFileBase FileData)
{
/*
*
* Do something with the FileData
*
*/
return "Upload OK!";
}
しかし、これはまだ発火しません。
誰でも、コントローラのアップロードアクションのシグネチャを正しく記述して取得できるようにして、実際に起動するようにできますか?その後、自分でファイルデータの処理を処理できます。メソッドアクションを起動するための助けが必要です。
public string Upload(HttpPostedFileBase FileData) {}
正しい-uploadifyによってアップロードされたファイルはFileDataにバインドされます。ファイルを取得するためにRequest.Filesにアクセスする必要はありません。これにより、モックとテストが困難になります。
アクションがまったく実行されない場合(つまり、デバッグを試みて、メソッド内のブレークポイントにヒットするかどうかを確認してください)、問題はおそらく「スクリプト」の値です-仮想ディレクトリで実行していますか?その場合は、ディレクトリの名前を前に置く必要があります。 Uploadifyは絶対パスを使用しています。
つまり、 'script:'/virtual_directory/Placement/Upload '
現在、uploadifyは http:// localhost/Placement/Upload に送信しています。
また、ルートデバッガー( http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx )を使用して、ルートがマップされている場所を確認してください。
問題は、アップロード先のアクションがPostに設定されていることを指定する必要があることかもしれません... Getアクションとしてのアクションでは機能しません。
したがって、この:
public string Upload(HttpPostedFileBase FileData)
{
//do something
}
これでなければなりません:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload(HttpPostedFileBase FileData)
{
//do something
}
また、サイトの「ログイン済み」セクションでこれを使用している場合は、uploadifyと認証に関する既知のバグをここで確認する必要があることに注意してください: http://geekswithblogs.net/apopovsky/ archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
また、余談ですが、MVCでファイルのアップロードを処理する方法はいくつかあります(Rory Fitzpatrickの提案に従ってRequest.Filesを使用し、アクション定義でHttpPostedFileBaseファイルを引数として渡します)。 Uploadifyを機能させるために、実際には問題になりません。
これは、ファイルアップロードを実装する必要があった方法ではありません。現在のRequestオブジェクトを使用して、投稿されたファイルのコレクションに飛び込むパラメーターのないアクションメソッドがありました。
私の実装からのいくつかのサンプルコード:
[AcceptVerbs(HttpVerbs.Post)]
public ContentResult Upload() {
if (Request.Files.Count > 0 && Request.Files[0].ContentLength > 0) {
HttpPostedFileBase postedFile = Request.Files[0];
// Do something with it
}
}
もちろん、このためのテストを書くことはPITAになります。それを機能させるには、いくつかのオブジェクトをモックする必要があります。次に例を示します。
var mockHttpContext = mocks.StrictMock<HttpContextBase>();
var mockRequest = mocks.StrictMock<HttpRequestBase>();
var postedFile = mocks.StrictMock<HttpPostedFileBase>();
var postedFileKeyCollection = mocks.StrictMock<HttpFileCollectionBase>();
mockHttpContext.Expect(x => x.Request).Return(mockRequest).Repeat.Any();
mockRequest.Expect(x => x.Files).Return(postedFileKeyCollection).Repeat.Any();
postedFileKeyCollection.Expect(x => x[0]).Return(postedFile).Repeat.Any();
postedFileKeyCollection.Expect(x => x.Count).Return(1);
postedFile.Expect(f => f.ContentLength).Return(1024);
postedFile.Expect(f => f.InputStream).Return(null);
IoCを使用して具体的な実装をコントローラーに注入すると、投稿されたファイルにインターフェースを作成し、それを模擬する方が簡単です。
これは主にこの投稿に基づいていたと思います: テストとモックを含むASP.NET MVCでのHTTPファイルアップロードの実装
これに対する私の完全な解決策はあなたの問題を解決するかもしれません。それが役に立てば幸い。
http://zootfroot.blogspot.com/2010/12/mvc-file-upload-using-uploadify-with.html
ドキュメントを読んでいると、ファイルの配列を送信しているようです。やってみました:
public string Upload( HttpPostedFileBase[] fileData )
また、デフォルトのモデルバインダーがHttpPostedFileBaseで機能せず、Roryのメカニズムを使用するか、独自のモデルバインダーを作成する必要がある場合もあります。
これが私のシンプルなRazorビューです(レイアウトマスターにはJavascriptバンドルがあります)
@{
ViewBag.Title = "Upload Email CSV";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript" src="@Url.Content("~/Scripts/Uploadify/jquery.uploadify.js")"></script>
<script type="text/javascript">
$(function () {
var uploadUrl = "@Url.Content("~/UploadFile/UploadEmailCSV/")";
var uploadSWF = "@Url.Content("~/Scripts/Uploadify/uploadify.swf")";
var uploadifyButtonImage = "@Url.Content("~/Scripts/Uploadify/uploadify.swf")";
$('#file_upload').uploadify({
'fileSizeLimit': '0',
'buttonImage': '/uploadify/browse-btn.png',
'swf': uploadSWF,
'uploader': uploadUrl,
'onUploadSuccess': function(file, data, response) {
alert('The file was saved to: ' + data);
}
});
});
</script>
<h2>Upload a comma separated list of email addresses</h2>
@using (Html.BeginForm("UploadEmailCSV", "UploadFile", FormMethod.Post, new { @class = "form-horizontal", @enctype = "multipart/form-data", @id = "frmUploadFiles" }))
{
<input type="file" name="file_upload" id="file_upload" />
}
これが制御方式です
public ActionResult UploadEmailCSV()
{
var uploadedFile = Request.Files["Filedata"];
if (uploadedFile != null && uploadedFile.ContentLength > 0)
{
var filePath = Path.Combine(Server.MapPath("~/UploadedFiles"), string.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(uploadedFile.FileName), DateTime.Now.Ticks, Path.GetExtension(uploadedFile.FileName)));
uploadedFile.SaveAs(filePath);
return Content(string.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(uploadedFile.FileName), DateTime.Now.Ticks, Path.GetExtension(uploadedFile.FileName)));
}
return Content("Error Uploading file!");
}
それでおしまい!