понедельник, 14 октября 2013 г.

Выгрузка файлов из ASP .Net приложения

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

Решение получается достаточно простым. Я не буду его переделывать, у меня в качестве параметра указывается id записи в табличке, через Entity Framework этот файл извлекается. У таблички 3 поля: Id, имя файл и сами данные файла.
Теперь о проекте. Создается пустой Web-проект. В него добавляется страницы aspx и ее обработчик загрузки имеет вид:

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.QueryString["id"] != null)
    {
 
        Guid id = Guid.Parse(Request.QueryString["id"]);
        FileRepository.Server.Data.FileRepositoryContext context = new FileRepository.Server.Data.FileRepositoryContext();
        var storedFile = context.StoredFiles.FirstOrDefault(f => f.Id == id);
        if (storedFile != null)
        {
            Response.ContentType = "application/unknow";
            Response.AddHeader("Content-Disposition""attachment;filename=\"" + HttpUtility.UrlPathEncode(storedFile.FileName) + "\"");
            Response.OutputStream.Write(storedFile.Data, 0, storedFile.Data.Length);
        }
        else
        {
            Response.Write("Файл с ID='" + id.ToString() + "' не найден");
        }
    }
}

Все.
В моем случае, т.к. станица называется webForm1.aspx доступ можно получать по ссылке вида: http://localhost:1093/webForm1.aspx?id=E52694BF-3C76-434F-B7EC-DEF3BF5C2A1D
Пара комментариев. Если не воспользоваться HttpUtility.UrlPathEncode, то для русских имен файлов, в некоторых браузерах могут возникнуть проблемы. При вызове HttpUtility.UrlPathEncode, с кодировкой проблемы не возникают.
И второе. Если анализировать расширение файлов, то можно подсказывать браузеру тип контента. Вместо unknow, для pdf можно указать "application/pdf"; для картинок jpeg - "image/jpeg" и т.д.

4 комментария:

  1. А можно узнать, почему вы не использовали HttpHandler?

    ОтветитьУдалить
    Ответы
    1. Ну а как же дух охоты?
      Ну а если серьезно, то хотелось попробовать такой способ. Но, в большинстве случаев правильнее использовать HttpHandler.

      Удалить
  2. Что-то не удалось выгрузить файл этим способом ,На сервере формируется файл doсx размером 66Кб на клиента выгружается 70Кб, Ворд ругается, но всё-же открывает этот битый файл,игнорируя лишние 4Кб, Может ещё как-то нужно указать размер передаваемого файла?

    ОтветитьУдалить
    Ответы
    1. Проверьте, что у вас формирование файла завершилось до отдачи на клиента. Проверьте, как у вас открывается файл с сервера (вы же можете получить к нему доступ). Попробуйте скачать не с этого браузера/компьютера, может у вас троян какой-то в файлы что-то дописывает.

      Удалить