PlatformNotSupportedException при сохранении файла из Silverlight через универсальный обработчик - PullRequest
0 голосов
/ 31 июля 2010

У меня есть приложение Silverlight, размещенное на сайте ASP.NET, с помощью которого я запускаю 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);

Теперь вот код ProcessRequest из HttpDownloadHandler.ashx

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 не принимает заголовок ответа должным образом ,

Можно ли что-нибудь сделать для решения этой проблемы? Я открыт для предложений по изменению способа, которым я делаю это, конечно.

Ответы [ 2 ]

1 голос
/ 01 августа 2010

Насколько я знаю, диалог сохранения будет вызываться только в событии нажатия кнопки, поэтому при получении ответа http вы вообще не получите разрешение на открытие диалогового окна сохранения.

Что вы должны сделать, так это то, что в вашем событии щелчка любой кнопкой, возможно, кнопка загрузки, в событии щелчка вы должны вызвать File Dialog и открыть поток файлов, который вы будете использовать позже, когда получите ответ веб-сервера.

1 голос
/ 31 июля 2010

Ответ отправляется в Silverlight, а не в веб-браузер (поэтому браузер не будет обрабатывать файл CSV и отображать диалоговое окно сохранения файла). Вам необходимо инициировать запрос непосредственно из веб-браузера (например, через 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>

Кроме того, вы, вероятно, могли бы сделать то же самое с помощью HTML DOM, полностью из Silverlight. Ссылка выше имеет основы относительно этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...