Мне нужно реализовать операцию, в которой пользователь запрашивает файл, который занимает некоторое время (2 - 4 минуты). После этого пользователю необходимо загрузить файл, преимущественно через ASP.NET (чтобы использовать средство загрузки браузера). Только указанный пользователь может скачать этот файл.
Вот как я пытался это сделать:
Сначала я построил дуплексный сервис wcf. Пользователь вызывает его с необходимыми ему данными, а затем начинает генерацию файла, уведомляя о ходе выполнения по каналу обратного вызова. В конце концов, сервис должен отправить пользователю URL-адрес, который он будет использовать для загрузки файла. Эта часть отлично работает.
Я сохранил файл во временную папку в папке asp_data, чтобы предотвратить прямой доступ к нему. Затем я создал страницу aspx для получения токена (каким бы он ни был), проверки его на соответствие текущему пользователю с заданным сроком действия и замены ответа файлом.
Тогда все стало грязно. Я не знаю, как правильно сгенерировать токен через WCF, вернуть его клиенту и использовать его на странице загрузки. Я пробовал два разных подхода, но я думаю, что отказываюсь от обоих:
Создайте guid для файла, зашифруйте его внутри FormsAuthenticationTicket (с информацией о пользователе и сроком действия) и отправьте его клиенту. Затем клиент использует зашифрованную строку тикета в качестве токена для страницы загрузки, которая проверяет пользователя в тикете по текущему, проверяет срок действия, извлекает guid и отправляет файл обратно. Проблема в том, что сгенерированная зашифрованная строка становится действительно большой, непригодной для использования в URL.
Создайте направляющую для файла, сохраните ее в тикете (с данными проверки и путем к файлу) в сеансе httpcontext. служба wcf затем передает guid клиенту, который использует его для доступа к странице загрузки. Страница загрузки проверяет сеанс, извлекает билет, обслуживает файл. Проблема в том, что у меня возникли проблемы с доступом к сеансу в операции WCF. Пользователь запрашивает файл, сервер запускает поток, чтобы сгенерировать файл и выполнить обратные вызовы, поэтому первый вызов сервера возвращает (ничего). Когда я успешно завершил создание файла, поток обратного вызова пытается получить доступ к сеансу, сохранить билет и вернуть guid пользователю в обратном вызове FinishOperationXXX. Однако я не могу получить доступ к сеансу, потому что он, кажется, больше не доступен для потока обратного вызова.
Я не хочу использовать базу данных для этого, и я пытаюсь избежать загрузки файла через сам WCF, но мне нужно, чтобы это работало. Думаю, мне удастся как-то это сделать, но мне интересно:
Я делаю это трудным путем?
Кто-нибудь знает, как реализовать что-то подобное?