2016-03-30 10 views
2

ファイルを処理するアクションを持つMVCアプリケーションがあります。ユーザーがダウンロードを開始した場合、現在のユーザーがダウンロードを完了するまで、ユーザーは新しいダウンロードを開始できないという要件があります。既存アプリケーションのMVC c#でのダウンロード

単純に言えば、ユーザーは一度に1つのファイルしかダウンロードできません。しかし、私は単にユーザーの要求をブロックしたいのではなく、既存のものをダウンロードしているため、新しいものをダウンロードできないことを知らせたいと思っています。

私の質問は、ダウンロードが開始されてまだ完了していないときにどのように追跡していますか?私は最初IISの動的IP制限に目を向けましたが、問題はエンドユーザーが信頼できるものではないかもしれないプロキシの層にレイヤーの背後に座っている可能性があることです。コードでこれを行う方法はありますか?

また、進行中のストリームを作成するFileWebRequest/FileWebResponseを使ってみました。しかし、新しいリクエストが入ったときに新しいアクションとして入力され、前のストリームがまだ進行中かどうかを確認する方法はわかりません。

public async Task<ActionResult> Download() 
    { 
     Session["IsDownloading"] = true;    
     await ServeFiles(); 
     return View("Index"); 
    } 

public ActionResult CheckStatus() 
    { 
     var message = Session["IsDownloading"] ?? "Null"; 
     return Content(message.ToString()); 
    } 
private async Task ServeFiles() 
{ 
    try 
    { //Download async 
    } 
    finaly 
    { 
     Session["IsDownloading"] = false; 
    } 
} 

***********************更新******************* **

サンプルコードを更新しました。 ダウンロードは、ダウンロードしている間に、CheckStatusを呼び出そうとしていましたが、ダウンロードが進行中に応答しません。ダウンロードが完了したときのみ。

私はここにプロジェクトソリューションを追加しました。 https://github.com/janmchan/DownloadThrottling.git

***********************アップデート2016年4月4日**********

後私はそのセッション(私はSQLServerを使用していることがわかった)の検索のビットがリクエストの最後に保存されるので、ユーザーが2つの同時リクエストを管理しても、セッション変数はリクエストの最後まで更新されませんセッションの情報は信頼できません。だから今、値を更新した直後に手動でセッション状態を保存する方法を探しています。

+0

セッションはブラウザ固有のものです(つまり、Cookieベースであり、各ブラウザがCookieを別々に処理するため)。だから(別のところで言及したように)セッションセキュリティをバイパスするために別のブラウザを開くだけで済ませなければならない。ただし、セッションを使用する場合は、セッションフラグを設定してからダウンロードするファイルにブラウザをリダイレクトするだけで済みます。これにより、ダウンロードが開始される前にセッション変数が更新されます。 –

+0

また、特定のファイルを参照するためにオンザフライで生成された一意のダウンロードIDと組み合わせることもできます。ダウンロードが開始されると、そのIDのダウンロード時にデータベースにマークし、再度使用されないようにします。 –

答えて

0

最終的な解決方法は、@ eugenの答えと似ていますが、セッションの代わりにすぐに有効なデータキャッシュ(MemoryCache)を使用して、要求が完了するのを待たないでください。これは処理中ですが、アプリケーションサーバーが負荷分散されていても、セッションが確立されるとクライアントのインフラストラクチャによって残りのサーバーに対して同じサーバーセットが使用されることが保証されているセッションの

私はErik Funkenbuschのコメントに同意します。このコメントは、ユーザーが簡単に回避できるということに同意します。この解決策はこの特定の要件にのみ該当します。

0

あなたは3つのことが必要だと思います:ユーザーを特定し、既存のダウンロードがあるかどうかを+ブロックで確認します。

最も簡単な方法は、Session ["isDownloading"] = trueを設定することです。これを確認してください。ダウンロードが完了したら、それをfalseに設定します。

クライアントからダウンロードを開始するときは、javascriptを使用してCheckIsDownloadingアクションを呼び出すことができます。また、OKを指定してServeを呼び出してファイルを取得することもできます。

サーブで再度チェックし、jsをハックしてダウンロード要求を行うシナリオを避けるためにダウンロードしている場合はブロックします。

注:ログインしておらず、ダウンロードが1回だけであることを確認したい場合は、ユーザーID部分を実行するのは難しいです。彼はいつでもクッキーを削除して( - >新しいセッション)、新しいダウンロードを行うことができます。

+0

私はこれを試しましたが、正しく動作するように見えませんでした。そこでServe Actionの開始時にSession ["IsDownloading"] = trueを追加し、ダウンロード後にfalseに更新しました。その後、セッションを読み込む別のアクションCheckStatusを作成しましたが、ブロックされたように見えて、ダウンロードが完了するまで応答しません。 – MichaelChan

+0

あなたはブロックされていることを確信していません。これをデバッグして、それは奇妙なことだろう。クライアントとサーバーの両方の実装で質問を更新することができます。実際のファイル読み取りコードを含める必要はありません – eugen

+0

質問とコードが更新されました。あなたがダウンロード(Download1/2)を試みて、チェックステータスをクリックしようとすると、ダウンロードが完了するまで応答しません。 – MichaelChan

関連する問題