2009-09-01 10 views
0

Google GearsとASP.NETを使用してファイルをアップロードしようとしています... HttpRequest APIがブロブを受け入れることができると思います。Google GearsとASP.NETまたはPHPを使用してファイルをアップロード

私はページにFileUploadコントロールを持っています。

<asp:FileUpload runat="server" ID="File1" /> 

その後はJavaScript

var file1 = document.getElementById("<%# File1.ClientID %>"); 
var desktop = google.gears.factory.create('beta.desktop'); 

file1.onclick = function() 
{ 
    desktop.openFiles(openFilesCallback, 
     { 
      singleFile: true, 
      filter: ["image/jpeg"] 
     } 
    ); 
    return false; 
} 

function openFilesCallback(files) 
{ 
    if(files.length == 0) 
    { 
     alert("No files selected"); 
    } 
    else 
    { 
     // 1MB = 1024 * 1024 bytes 
     if(files[0].blob.length > (1024 * 1024)) 
     { 
      alert("File '" + files[0].name + "' is too big to upload"); 
     } 
     else 
     { 
      uploadFile(files[0]); 
     } 
    } 
} 

function uploadFile(file) 
{ 
    var up = google.gears.factory.create("beta.httprequest"); 
    up.open("POST", "upload.ashx"); 
    up.send(file.blob); 
} 

はしかし、私はハンドラでそれを処理する方法がわからないです。

public void ProcessRequest (HttpContext ctx) 
{ 
    ctx.Response.ContentType = "text/plain"; 
    ctx.Response.Write("Hello World"); 
    ctx.Response.Write(ctx.Request.Files.Count.ToString()); 
    ctx.Response.Write(ctx.Request.Form.Count.ToString()); 
} 

私は最後の二つの文のいずれかにブレークポイントを設定した場合、私がいない場合は、両方Files.CountForm.Countリターン0私はFirebugので例外を取得:Component returned failure code: 0x80004001 (NS_ERROR_NOT_IMPLEMENTED)

私が使用できない場合Gears経由でアップロードするPOSTは、PUTを使用して行うことはできますか?

編集: PHPコード(私は両方の言語でそれをやりたいので)だけでなく罰金になります

答えて

2

私はあなたの問題の根本は、ギアとあなたが実際にマルチパートフォームを使用していないということだと思います/ dataアップロードメカニズムを使用する代わりに、POSTリクエスト自体にファイルデータを実際に送信します。

あなたがしなければならないことは、実際には入力ハンドラからリクエストストリームを読み込んでデータを取得することです。あなたのコードは次のようになります。あなたは、ファイルへの書き込みやデータベースは例外処理だけでなく、あなた次第ですし、新しいファイルを作成したり、追加したいかどうかを考え出すかどうかもちろん

public void ProcessRequest (HttpContext ctx) 
{ 
    var filePath = "SomePath/ToWrite/Filedata.dat"; 
    var stream = ctx.Request.InputStream; 
    var buffer = new byte[stream.Length]; 
    stream.Read(buffer,0,buffer.Lenght); 
    using(var fileStream = new FileStream(filePath,FileMode.Create)) 
    { 
     fileStream.Write(buffer, 0, buffer.Length); 
    } 
} 

既存のファイルなど。また、コードのファイルサイズが1MBに制限されていたため、バッファ長を制限することはありませんでした。大規模なブロックを処理する可能性がある場合は、データがなくなるまで、小さなバッファを選択してストリームから読み込む必要があるかもしれません(これはストリームの長さがint.maxvalueの場合に起こります)。

元のファイルの名前のようなものを含める必要がある場合は、いくつかのオプションがあります。 URLをクエリパラメータとして送信するだけです(正しくエンコードされていることを確認してください)。次に、ctx.Request.QueryString ["fileName"]などから読み込むことができます。

さらに、必要なデータをクライアント側のより複雑なオブジェクトに入れ、JSONを使用してすべてシリアル化してPOSTに配置することもできます。あなたが最も可能性の高いSystem.Web.ServicesからDataContractJsonSerializerが必要になりますので、あなたは、サーバー側でそれをデシリアライズする必要があります

function uploadFile(file) 
{ 
    var up = google.gears.factory.create("beta.httprequest"); 
    up.open("POST", "upload.ashx"); 
    var fileInfo = { Name: file.name, Data: file.blob, someOtherData: ...}; 
    up.send(JSON.stringify(fileInfo)); 
} 

:だからあなたのクライアントコードは次のようになります。もう1つの選択肢はJames Newton-King(http://james.newtonking.com/pages/json-net.aspx)のJson.Netライブラリです。

internal class FileInfo 
{ 
    public string Name { get; set; } 
    public byte[] Data { get; set; } 
    // .. some other data 
} 


public void ProcessRequest(HttpContext ctx) 
{ 
    var serializer = new DataContractJsonSerializer(typeof(FileInfo)); 
    FileInfo fInfo = (FileInfo)serializer.ReadObject(ctx.Request.InputStream); 
    var path = basePath + fInfo.Name; 
    using(var fileStream = new FileStream(path,FileMode.Create)) 
    { 
     fileStream.Write(fInfo.Data,0,fInfo.Data.Length); 
    } 
} 

私は私がいることを、PHPの土地:)

+0

おかげでてきたので、長い、長い、長い時間がかかった....私はPHP側の多くを助けることができない怖いです(既にmultipart-form/dataを使用していたので問題はなかった)。 JSONを使用してデシリアライズするのではなく、追加のメタデータのリクエストヘッダーを設定しています。 – SamWM

関連する問題