Хорошо, у меня есть несколько идей по этому поводу:
Собираетесь ли вы использовать Silverlight SaveDialog
для загрузки файла? Прежде всего, и я думаю, что вы это знаете, это единственный способ сохранения файлов на компьютер пользователя с помощью Silverlight 3.
Если вы собираетесь использовать этот метод, вам понадобится управляемое пользователем событие для сохранения файла (т. Е. Нажатие кнопки).
Так что да, вам придется пойти на этот дополнительный вызов, но не внутри кода takeQueryParamsAsync_Completed
. Что вы можете сделать, так это активировать кнопку или что-то еще, что сообщит пользователю, что отчет сгенерирован, и заставит его нажать кнопку download
. Есть и другие варианты, хотя недавно я реализовал опцию загрузки, в которой использовалось перенаправление URL-адреса на URL-адрес файла на сервере, и это позволило мне обойти весь вопрос (Нет имени файла по умолчанию, не могу просто открыть файл, но имеет сначала сохранить его на жесткий диск и т. д.).
Что касается вопроса с государством. Это действительно зависит от того, где вы храните сгенерированный отчет. Вы храните его на жестком диске, в базе данных или храните в памяти? Это влияет на то, как вы можете вызвать файл. Один из простых способов сделать это - вернуть клиенту ключ, который он передает обратно на сервер в виде ключа, связывающего файл. Таким образом, вам не нужно поддерживать состояние между службой WCF и Silverlight.
EDIT
Что ж, на стороне Wcf Service вам потребуется дополнительная услуга.
Мой выглядит примерно как
<service behaviorConfiguration="NewBehavior" name="ALMWCFHost.FileProvider.FileService">
<endpoint address="" behaviorConfiguration="NewBehavior1" binding="webHttpBinding"
bindingConfiguration="" name="File" contract="ALMWCFHost.FileProvider.IFileService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8021/Files/" />
</baseAddresses>
</host>
</service>
Вам также придется создать новое поведение конечной точки
<endpointBehaviors>
<behavior name="NewBehavior1">
<webHttp />
</behavior></endpointBehaviors>
Это создаст службу webHttp.
Теперь вы создадите несколько конечных точек:
[OperationContract, WebGet(UriTemplate = "GetFile/{filename}")]
Stream GetFile(string filename);
[OperationContract, WebGet]
Stream GetYCFile(string date, string type, string format);
[OperationContract, WebGet(UriTemplate = "GetFiles/Files.zip?filenames={querystring}")]
Stream GetFiles(string querystring);
Любая строка запроса, которую вы передаете с адресом, будет проанализирована в переменных.
Затем на стороне клиента Silverlight я просто создал пользовательский URI (в вашем случае, допустим, файл называется «NewReport.xls»), который указывает на вызов «GetFile / {имя файла}», тогда ваш Uri будет выглядеть что-то вроде http://localhost/FileService.svc/GetFile/NewReport.xls
Теперь все, что вы делаете, это переходите по этому URL с помощью чего-то вроде HtmlPage.Window.Navigate(page, "_self");
. Это позволит вам загрузить файл и остаться на той же странице Silverlight, что и вы.