Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Upload Download file на C# ASP.NET

3
07 апреля 2009 года
Green
4.8K / / 20.01.2000
ASP не знаю, отсюда и вопрос.
Надо организовать некий HTTP-сервер на который один клиент закачает файл, а другие смогут его забрать. Плюс ведется лог, кто (ip) когда закачал и кто когда забрал.
Поверх ещё много разной логики, но это основа.
Так вот думаю, свой сервер фигачить (HTTPListener) или использовать готовый(IIS) ?

Если не сложно, покажите простой пример, как будет выглядеть C# ASP код, принимающий и сохраняющий файл и код его отдающий.

На основе этого буду думать, вникать в ASP или нет.
Спасибо.
408
07 апреля 2009 года
Lei fang
265 / / 01.10.2005
Здесь есть пример достаточно простенький: http://www.codeproject.com/KB/aspnet/fileupload.aspx
показано как принять файл, сохранить его в БД даже и потом из БД извлеч и показать. (сделано очень хитро. Response.OutputStream.Write((byte[])dbRead["FileData"], 0, (int)dbRead["FileSize"]); //ты обратишься к какой-нибудь http://localhost/page.aspx, а начнется загрузка файла)
собственно там на примере картинки, но файл может быть каким угодно, и не обязательно сохранять в базу, можно и на файловую систему, а потом в asp на событие нажатия на какую-то кнопку перенаправлять пользователя к файлу, одновременно запоминая его айпи, время и т.д.
5
07 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
Так вот думаю, свой сервер фигачить (HTTPListener) или использовать готовый(IIS) ?

У IIS'а есть неприятная особенность - ограничение на размер закачиваемого файла. Это значение задается в его метабазе.


Код разметки Default.aspx:

Код:
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:FileUpload ID="FileUpload1" runat="server" &#111;&#110;Load="FileUpload1_Load"  />
        <asp:Button ID="Button1" runat="server" Text="Upload!" /><br />
        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
                <asp:HyperLink ID="url1" runat="server" Text='<%# Eval("Name") %>' NavigateUrl='<%# "~/Uploads/" + Eval("Name") %>' />
            </ItemTemplate>
            <SeparatorTemplate>
                <br />
            </SeparatorTemplate>
        </asp:Repeater>        
    </form>
</body>
</html>
Код страницы
Код:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;

public partial class _Default : System.Web.UI.Page {
    private readonly string uploads_dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads");

    protected void Page_Load(object sender, EventArgs e) {
    }

    protected void FileUpload1_Load(object sender, EventArgs e) {
        if (FileUpload1.HasFile) {
            HttpPostedFile user_file = FileUpload1.PostedFile;

            DirectoryInfo uploads = new DirectoryInfo(uploads_dir);
            if (!uploads.Exists)
                uploads.Create();

            string user_file_server_name = Path.Combine(uploads.FullName, Path.GetFileName(user_file.FileName));
            using (FileStream stream = new FileStream(user_file_server_name, FileMode.Create, FileAccess.Write, FileShare.None)) {
                byte[] buffer = new byte[4096];
                int bytes_read = 0;
                do {
                    stream.Write(buffer, 0, bytes_read);
                    bytes_read = user_file.InputStream.Read(buffer, 0, buffer.Length);
                } while (bytes_read > 0);
            }
        }
    }

    protected void Page_PreRender(object sender, EventArgs e) {
        DirectoryInfo uploads = new DirectoryInfo(uploads_dir);
        if (!uploads.Exists)
            uploads.Create();
        Repeater1.DataSource = uploads.GetFiles();
        Repeater1.DataBind();
    }
}
Файлы закачиваются в каталог Upload, их кликабельный список отображается на странице.
3
08 апреля 2009 года
Green
4.8K / / 20.01.2000
Спасибо за ответы!
Начал вникать в ASP.NET и появился вопрос: а то ли это, что мне надо? :)
Вот, хочу посоветоваться с Вами.
Стоит следущая задача.
Есть ряд приложений-клиентов, которые будут закачивать файлы (Download) автоматически по некоторому событию.
Есть "консоль администратора", с которой будут передаваться эти файлы (Upload) на сервер, для дальнейшей передачи клиентам.
Есть сервер, который принимает от администратора файлы и раздает их приложениям-клиентам, регистрируя кому чего отдал.
Т.е. по-существу это такая система автоматических апдейтов клиентских машин.
Все происходит по HTTP, но без использования браузеров, т.к. все автоматически. Т.е. мне не нужна генерация человеческих web-страниц.
Писать свой сервак (по-сути файлообменник) очень не хочется.

Поможет мне здесь ASP или я копаю не в ту сторону?
Может есть решение по-проще?
5
08 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
Поможет мне здесь ASP или я копаю не в ту сторону?

Тогда наверно не имеет смысла делать классические страницы, лучше воспользоваться Http-обработчиками (реализациями интерфейса IHttpHandler или IHttpAsyncHandler). Веб-сервер будет напрямую передавать им запрос.
Думаю, для такой задачи лучше сразу пользоваться асинхронными обработчиками, так как синхронные могут быстро заполнить все рабочие потоки на длительных файловых операциях.

З.Ы. Вообще, у меня как-то были мысли создать похожую систему обновления кое каких своих программ. К сожалению готовых полных (сервер, админка и клиентский модуль) решений не нашел, хотя может быть что-то такое есть в CruiseControl.NET (но туда нужно все проекты пересаживать).

3
08 апреля 2009 года
Green
4.8K / / 20.01.2000
Цитата: hardcase
Тогда наверно не имеет смысла делать классические страницы, лучше воспользоваться Http-обработчиками (реализациями интерфейса IHttpHandler или IHttpAsyncHandler). Веб-сервер будет напрямую передавать им запрос.
Думаю, для такой задачи лучше сразу пользоваться асинхронными обработчиками, так как синхронные могут быстро заполнить все рабочие потоки на длительных файловых операциях.

З.Ы. Вообще, у меня как-то были мысли создать похожую систему обновления кое каких своих программ. К сожалению готовых полных (сервер, админка и клиентский модуль) решений не нашел, хотя может быть что-то такое есть в CruiseControl.NET (но туда нужно все проекты пересаживать).



Почитал на счет IHttpAsyncHandler, в частности, вот это. Прикинул, что upload будет делать одна админская консоль, а download буду делать напрямую (не через обработчик, а заданием пути до файла).
И остановился все же на IHttpHandler:

Код:
using System;
using System.Web;
using System.IO;
using System.Net;


namespace WebApplication2
{
    public class Handler1 : IHttpHandler
    {
        private readonly string uploads_dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads");

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                DirectoryInfo uploads = new DirectoryInfo(uploads_dir);
                if (!uploads.Exists)
                {
                    uploads.Create();
                }

                for(int i=0; i < context.Request.Files.Count; i++)
                {
                    HttpPostedFile file = context.Request.Files;
                    if (file.ContentLength > 0)
                    {
                        file.SaveAs( Path.Combine(uploads.FullName, Path.GetFileName(file.FileName)) );
                    }
                }

                context.Response.Write("OK");
            }
            catch (System.Exception ex)
            {
                context.Response.Write("Trouble: " + ex.Message);
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
3
08 апреля 2009 года
Green
4.8K / / 20.01.2000
Возник ещё вопрос: как мне в ProcessRequest узнать IP клиента?

Вопрос снят:
context.Request.UserHostAddress;
5
08 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
Почитал на счет IHttpAsyncHandler, в частности, вот это.

Ссылка интересная спасибо. :)

Я бы вот так написал:

Код:
using System;
using System.Web;
using System.IO;
using System.Net;


namespace WebApplication2
{
    public class Handler1 : IHttpHandler
    {
        private[COLOR=Red] [COLOR=Black]static [/COLOR][/COLOR]readonly string uploads_dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads");

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                DirectoryInfo uploads = new DirectoryInfo(uploads_dir);
                if (!uploads.Exists)
                {
                    uploads.Create();
                }

                foreach(HttpPostedFile file in context.Request.Files)
                {
                    if (file.ContentLength > 0)
                    {
                        file.SaveAs( Path.Combine(uploads.FullName, Path.GetFileName(file.FileName)) );
                    }
                }

                context.Response.Write("OK");
            }
            catch (System.Exception ex)
            {
                context.Response.Write("Trouble: " + ex.Message);
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}


Если расширение файла у хэндлера отлично от ashx, с IIS'ом одна тонкость будет (во всяком случае с 6м): нужно добавлять ASP.NET ISAPI фильтр на это расширение и отключить проверку существования файлов, иначе http-обработчики не будут вызываться (подразумевается что файла TestHandler.htm нет на диске)
 
Код:
<configuration>
    <sytem.web>
...
        </httpHandlers>
            <add verb="*" path="TestHandler.htm" type="TestHandler"/>
        </httpHandlers>
...
3
09 апреля 2009 года
Green
4.8K / / 20.01.2000
Цитата: hardcase

Я бы вот так написал:
 
Код:
foreach(HttpPostedFile file in context.Request.Files)
                {
                    if (file.ContentLength > 0)
                    {
                        file.SaveAs( Path.Combine(uploads.FullName, Path.GetFileName(file.FileName)) );
                    }
                }


Оказалось, что foreach здесь не работает, т.к. энумератор оперирует именами файлов, а не их содержимым. Т.е. file будет типа string, а не HttpPostedFile.
А вот разындексирование возвращает HttpPostedFile.
Короче, странная эта колекция System.Web.HttpFileCollection.

5
09 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
Короче, странная эта колекция System.Web.HttpFileCollection.

Да, действительно странная (я в браузере тот ответ фигачил - в МСДН не смотрел), что-то вроде словаря, а интерфейс совсем не словарный; вон и перечисление толком не предоставляет.

3
15 апреля 2009 года
Green
4.8K / / 20.01.2000
А как мне теперь сделать, чтоб по-дефолту, т.е. когда я набираю только адрес сайта без пути к конкретным страницам/обработчикам, срабатывал один из моих обработчиков, а не выводился Directory Listing ?
5
15 апреля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
А как мне теперь сделать, чтоб по-дефолту, т.е. когда я набираю только адрес сайта без пути к конкретным страницам/обработчикам, срабатывал один из моих обработчиков, а не выводился Directory Listing ?


Установить в IIS-е дефолтный документ для данного сайта (там по умолчанию Default.aspx).
[ATTACH]3485[/ATTACH]

3
16 апреля 2009 года
Green
4.8K / / 20.01.2000
Цитата: hardcase
Установить в IIS-е дефолтный документ для данного сайта (там по умолчанию Default.aspx).
[ATTACH]3485[/ATTACH]


Я ещё до IIS не дошел. :)
Пока пользуюсь встроенным в VS сервером.

Попробовал через web.config

 
Код:
<system.web>
    <urlMappings enabled="true">
        <add url="~/Default.aspx" mappedUrl="~/Status.ashx"/>
        <add url="~/" mappedUrl="~/Status.ashx"/>
        <add url="~" mappedUrl="~/Status.ashx"/>
    </urlMappings>
    ..............


Первая строчка отрабатывает, т.е. при явном обращении к Default.aspx переадресуется на Status.ashx.

Остальные строки не работают :(
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог