0

ASP.NET サイトでホストされている Silverlight アプリケーションを使用しています。これを介して、CSV ファイルをユーザーのマシンに保存するために、ジェネリック ハンドラーへの HttpWebRequest を開始しています。

Silverlight アプリから、パラメーターを使用して Uri が作成され、CSV ファイルがサーバー側になります。ボタンをクリックすると、次のことがトリガーされます。

string httpHandlerName = "HttpDownloadHandler.ashx";
// CustomUri handles making it an absolute Uri wherever we move the handler.
string uploadUrl = new CustomUri(httpHandlerName).ToString();

UriBuilder httpHandlerUrlBuilder = new UriBuilder(uploadUrl);
httpHandlerUrlBuilder.Query = string.Format("{3}startdate={0}&enddate={1}&partnerId={2}", startDate, endDate, partnerId, string.IsNullOrEmpty(httpHandlerUrlBuilder.Query) ? "" : httpHandlerUrlBuilder.Query.Remove(0, 1) + "&");

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(httpHandlerUrlBuilder.Uri);
webRequest.Method = "POST";
webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);

ここで、HttpDownloadHandler.ashx の ProcessRequest コードを示します。

public void ProcessRequest(HttpContext context)
{
    _httpContext = context;

    string partnerId = _httpContext.Request.QueryString["partnerId"];
    string startDate = _httpContext.Request.QueryString["startDate"];
    string endDate = _httpContext.Request.QueryString["endDate"];

    ExportCsvReport exportCsv = new ExportCsvReport();
    _csvReport = exportCsv.ExportMemberRegistrationReport(partnerId, startDate, endDate);

    context.Response.Clear();
    context.Response.AddHeader("content-disposition", "attachment; filename=Report.csv");
    context.Response.ContentType = "text/csv";
    context.Response.Write(_csvReport);
}

ファイルの保存ダイアログが表示されない場合に返される HttpResponse ヘッダー情報を次に示します。

{System.Web.HttpResponse}
Buffer: true
BufferOutput: true
Cache: {System.Web.HttpCachePolicy}
CacheControl: "private"
Charset: "utf-8"
ContentEncoding: {System.Text.UTF8Encoding}
ContentType: "text/csv"
Cookies: {System.Web.HttpCookieCollection}
Expires: 0
ExpiresAbsolute: {1/1/0001 12:00:00 AM}
Filter: {System.Web.HttpResponseStreamFilterSink}
HeaderEncoding: {System.Text.UTF8Encoding}
Headers: 'context.Response.Headers' threw an exception of type 'System.PlatformNotSupportedException'
IsClientConnected: true
IsRequestBeingRedirected: false
Output: {System.Web.HttpWriter}
OutputStream: {System.Web.HttpResponseStream}
RedirectLocation: null
Status: "200 OK"
StatusCode: 200
StatusDescription: "OK"
SubStatusCode: 'context.Response.SubStatusCode' threw an exception of type 'System.PlatformNotSupportedException'
SuppressContent: false
TrySkipIisCustomErrors: false

サイトが稼働しているときに、Silverlight アプリ内から開始せずに localhost/HttpDownloadHandler.ashx に移動すると、[ファイルの保存] ダイアログが正常に表示されます。これは、Silverlight が応答ヘッダーを適切に受け入れていない場合のようです。

これに対処するためにできることはありますか?もちろん、これを行う方法を変更するための提案を受け入れます。

4

2 に答える 2

1

私の知る限り、保存ダイアログはボタン クリック イベントでのみ呼び出されるため、http 応答を受信すると、保存ダイアログ ボックスを開く権限がまったく得られません。

あなたがすべきことは、任意のボタンクリックイベント、おそらくダウンロードボタンで、クリックイベントでファイルダイアログを呼び出し、後でWebサーバーの応答を受け取ったときに使用するファイルストリームを開く必要があります。

于 2010-08-01T10:14:50.570 に答える
1

応答は Web ブラウザーではなく Silverlight に送られます (そのため、ブラウザーは CSV ファイルを処理せず、ファイル保存ダイアログを表示しません)。Web ブラウザーから (たとえば JavaScript を介して) 直接要求を開始する必要があります。Silverlight の HTML/JavaScript ブリッジを使用すると、これを非常に簡単に行うことができます。

JavaScript ブリッジの適切な例は、ここにあります。

次のようなロジックを追加する必要があります。

HtmlPage.Window.Invoke("startDownload", httpHandlerUrlBuilder.Uri.ToString());

そして JavaScript で:

<script type="text/javascript">
function startDownload(url){
    // you'll probably need to redirect
    // to a hidden iFrame to actually 
    // kick off the download, by
    // setting the location to
    // the url
    // or ... some other option
    // there are a number of 
    // different ways.
}
</script>

また、Silverlight 内から完全に HTML DOM を介して同じトリックを行うこともできます。上記のリンクには、それに関する基本もあります。

于 2010-07-31T01:25:42.653 に答える