0

我有一个托管在 ASP.NET 站点中的 Silverlight 应用程序,通过该应用程序我将 HttpWebRequest 启动到通用处理程序,以便将 CSV 文件保存到用户的计算机。

在 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

当我在站点启动时导航到 localhost/HttpDownloadHandler.ashx 时,没有从 Silverlight 应用程序中启动它 - 保存文件对话框看起来很好,这似乎是 Silverlight 没有正确接受响应标头的情况。

有什么办法可以解决这个问题吗?我当然愿意接受改变我这样做的方式的建议。

4

2 回答 2

1

响应将发送到 Silverlight,而不是 Web 浏览器(因此浏览器不会处理 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 回答
1

据我所知,保存对话框只会在按钮点击事件中被调用,所以当您收到http响应时,您根本不会获得打开保存对话框的权限。

您应该做的是,在您的任何按钮单击事件中,可能是下载按钮,在单击事件中,您应该调用文件对话框并打开您稍后将在收到 Web 服务器响应时使用的文件流。

于 2010-08-01T10:14:50.570 回答