﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Веб мастеринг для ASP.NET</title><link>http://www.blogasp.net</link><description>Статьи о ASP.NET, AJAX, jQuery. Вебмастеринг под ASP.NET</description><copyright>Copyright blogasp.net. All rights reserved.</copyright><language>ru-ru</language><item><title>Об использовании SQL Function CONVERT</title><description>Автор: Андрей Шедько&lt;hr /&gt; Иногда возникает необходимость поменять формат данных например с &lt;strong&gt;datetime&lt;/strong&gt; в&lt;br /&gt;
&lt;strong&gt;nvarchar&lt;/strong&gt; или поменять формат выводимых данных. &lt;br /&gt;
Например в последнем моем сайте база данных почему-то не опознавала &lt;br /&gt;
тип данных date, а мне нужно было представить данные в виде короткой строки даты типа 27.07.2010. Что бы не заморачиваться с Custom DataFormatString, я использовал &lt;strong&gt;SQL&lt;/strong&gt; функцию &lt;strong&gt;CONVERT&lt;/strong&gt;, которая преобразует имеющийся тип данных к типу nvarchar используя следующий синтаксис: &lt;pre class="sql" name="code"&gt;SELECT CONVERT(nvarchar(11), ColumnName, 106) &lt;/pre&gt; В этом выражении первая часть - длина и тип данных к которым мы приводим, вторая часть - колонка с данным, которые нужно преобразовать, 106 - это код формата данных - dd.mm.yyyy.&lt;p&gt;&lt;/p&gt;
В результате мы преобразовали строку вида 27.07.2010 00:00:00 к с троке вида 27.07.2010</description><link>http://www.blogasp.net/blog/post.aspx?ID=17</link><pubDate>Mon, 01 Feb 2010 11:20:15 GMT</pubDate></item><item><title>Microsoft Ajax CDN. Часть 2.</title><description>Автор: Андрей Шедько&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;Продолжаем исследование новой фишки от &lt;b&gt;Microsoft&lt;/b&gt; - &lt;b&gt;Microsoft AJAX Content Delivery Network&lt;/b&gt;. &lt;br /&gt;Как использовать:&lt;br/&gt;&lt;pre class="html" name="code"&gt;&lt;script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"&gt;&lt;/script&gt;&lt;/pre&gt;&lt;br /&gt;Очень интересная и важная новость для использующих &lt;b&gt;Microsoft AJAX&lt;/b&gt; - теперь весь &lt;span style="font-weight: bold"&gt;Java Script&lt;/span&gt; для &lt;span style="font-weight: bold"&gt;ScriptManager&lt;/span&gt; можно получать прямо из интернета, с сервера CDN, а не с Вашего хост сервера. Делается это за счет использования &lt;span style="font-weight: bold"&gt;EnableCdn="true"&lt;/span&gt;&lt;br /&gt;&lt;pre class="html" name="code"&gt;&lt;asp:ScriptManager ID="ScriptManager1" EnableCdn="true" runat="server" /&gt;&lt;/pre&gt;&lt;br /&gt;Для меня однако остается под большим вопросом одна из заявленных возможностей &lt;b&gt;CDN&lt;/b&gt; от &lt;b&gt;Microsoft&lt;/b&gt; - количество их серверов по всему миру (что я вляется основой для быстрой доставки контента). Я лично пока что продолжаю использовать &lt;b&gt;Google CDN&lt;/b&gt;, так как уверен, что серверов у них поболе. Что будет дальше посмотрим, так как  &lt;b&gt;Microsoft&lt;/b&gt; прилагает серьезные усилия для продвижения и развития этой технологии, которые в будущем, возможно, перевесят плюсы &lt;strong&gt;Google CDN&lt;/strong&gt;.</description><link>http://www.blogasp.net/blog/post.aspx?ID=16</link><pubDate>Sat, 02 Jan 2010 11:53:21 GMT</pubDate></item><item><title>Microsoft Ajax CDN</title><description>Атор статьи: Андрей Шедько.&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;Весьма любопытная вещь просиходит - Майкрософт признает и начинает активно использовать&lt;span style="font-weight: bold"&gt; jQuery&lt;/span&gt; для веб-разработок в среде &lt;span style="font-weight: bold"&gt;ASP.NET&lt;/span&gt;. В скором времени напишу об это подробнее, когда изучу все особенности. Будет чрезвычайно любопытно сравнить особенности и скорость &lt;span style="font-weight: bold"&gt;Microsoft CDN&lt;/span&gt; и &lt;span style="font-weight: bold"&gt;Google CDN&lt;/span&gt;, выполняющих аналогичые задачи.</description><link>http://www.blogasp.net/blog/post.aspx?ID=15</link><pubDate>Tue, 20 Oct 2009 16:40:32 GMT</pubDate></item><item><title>Cистема рейтинга для сайта на ASP.NET</title><description>&lt;span style="font-style: italic"&gt;Автор: Андрей Шедько&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;&lt;h1&gt;Общая схема работы&lt;/h1&gt;
Для клиентской части мы используем взрывную смесь состоящую из &lt;span style="font-weight: bold"&gt;CSS&lt;/span&gt;, который будет отвечать за отображение состояния нашего рейтинга в зависимости от действий пользователя, а так же &lt;span style="font-weight: bold"&gt;AJAX&lt;/span&gt; и &lt;span style="font-weight: bold"&gt;jQuery&lt;/span&gt; для передачи данных &lt;span style="font-weight: bold"&gt;веб сервису&lt;/span&gt;, который будет отвечать за вычисление текущего рейтинга и передачу данных на сторону пользователя.&lt;h1&gt;Клиентская часть - CSS.&lt;/h1&gt;
Что бы не долго мучаться, для отображения самого рейтинга я взял разработку от Komodo Media. Скачать можно &lt;a href="http://www.komodomedia.com/blog/2007/01/css-star-rating-redux/" target="_blank"&gt;здесь&lt;/a&gt;. Объяснять подробности и приводить примеры кода смысла нет, так как это можно прочесть на сайте разработчика, обратите внимание только на класс, называемый ".current-rating", его мы будем использовать в нашем коде &lt;span style="font-weight: bold"&gt;jQuery&lt;/span&gt; и так же было добавлено свойство name="star", что позволит селектору&lt;b&gt; jQuery&lt;/b&gt; обрабатывать клики именно на ссылки рейтинга.
&lt;h1&gt;Сладкая парочка: &lt;strong&gt;AJAX+jQuery&lt;/strong&gt;&lt;/h1&gt;
Вот здесь кроется самое интересное - код &lt;strong&gt;jQuery&lt;/strong&gt;, который мы будем использовать для того, что бы придать жизнь нашему рейтингу.
Выглядит это так: 
&lt;pre class="js" name="code"&gt;
$(document).ready(function() {
//селектор выбирает все ссылки с именем "star"
$("a[name='star']").click(function() {
var value = $(this).text();
//для записи в базу данных передаем url документа, оцененного пользователем
var url = document.URL;
var params = "{star:'" + value + "', url:'" + url + "'}";        $.ajax({
            type: "POST"
//веб сервис и его веб метод
           url: "rating.asmx/getValue"
            contentType: "application/json; charset=utf-8"
            dataType: "json"
            data: params
            success: function(msg) {
//используем плагин jquery.blockUI.js для отображения пользователю
$.blockUI({ message: $('&lt;h2&gt;Спасибо! Ваш голос учтен.&lt;/h2&gt;'), css: { padding: '10px'} }); 
            setTimeout($.unblockUI, 1500); 
            var rating = msg
//отображаем текущий ретинг после действия пользователя
                switch (rating) {
                    case 1:                
$("#1").addClass("current-rating");
                        break;
                    case 2:                
$("#2").addClass("current-rating");
                        break;
                    case 3:
$("#3").addClass("current-rating");
                        break;                    
                    case 4:                
$("#4").addClass("current-rating");
                    break;
                    case 5:&lt;br /&gt;    
$("#5").addClass("current-rating");
                        break;
                }
            },
           error: function(onError) {
                alert("Ошибка. Перезагрузите страницу (F5).");
           }
        });
    });
});
&lt;/pre&gt;
Как видите нельзя сказать, что это крайне сложно (я так говорю после трех проведенных над этим кодом).
&lt;h1&gt;Веб-сервис. Подсчитываем рейтинг&lt;/h1&gt;
Здесь уже привычный нам и понятный код &lt;span style="font-weight: bold"&gt;&lt;strong&gt;VB.NET&lt;/strong&gt;&lt;/span&gt;. Главный веб метод:
&lt;pre class="vb" name="code"&gt;
Public Function getValue(ByVal star As Integer, ByVal url As String) As Integer
Dim currRating As Integer
 Dim con As String =configurationManager.ConnectionStrings("domvtae_comCS").ConnectionString
Dim rate As New SqlConnection(con)
'Строка команды на случай если рейтинг добавляется впервые
Dim ins As String = "INSERT INTO rating ([Url], [Votes], [Total], [CurrentRating]) VALUES(@Url, @Votes, @Total, @CurrentRating)"
'строка команды на случай если рейтинг уже есть
Dim upd As String = "UPDATE rating SET [Votes] = @Votes, [Total] = @Total, [CurrentRating] = @CurrentRating WHERE ([Url] = @Url)"
'проверка наличия записи
Dim have As Boolean = CheckRecords(url)
'Количество голосов
Dim vote As Integer = CurrentVotes(url)
'Общий рейтинг
Dim total As Integer = CurrentTotal(url)
vote = vote + 1
total = total + star
 If have = True Then
 currRating = total \ vote
 rate.Open()
 Dim cmdUpd As New SqlCommand(upd, rate)
 With cmdUpd.Parameters
 .AddWithValue("@Votes", vote)
 .AddWithValue("@Total", total)
 .AddWithValue("@CurrentRating", currRating)
 .AddWithValue("@Url", url)
 End With
cmdUpd.ExecuteNonQuery()
rate.Close()
Else
rate.Open()
vote = 1
total = star
Dim cmdIns As New SqlCommand(ins, rate)
 With cmdIns.Parameters
 .AddWithValue("@Url", url)
 .AddWithValue("@Votes", vote)
 .AddWithValue("@CurrentRating", star)
 .AddWithValue("@Total", total)
 End With
cmdIns.ExecuteNonQuery()
rate.Close()
currRating = star
End If
Return currRating
End Function
&lt;/pre&gt;
Функция, которая проверяет есть ли записи в таблице рейтинга для конкретного url
&lt;pre name="code" class="vb"&gt;
Private Function CheckRecords(ByVal url As String) As Boolean
        Dim result As Boolean
        Dim con As String = ConfigurationManager.ConnectionStrings("domvtae_comCS").ConnectionString
        Dim rate As New SqlConnection(con)
        Dim sel As String = "SELECT Count(Votes) FROM rating WHERE (Url = @Url)"
        Dim cmd As New SqlCommand(sel, rate)
        With cmd.Parameters
            .AddWithValue("@Url", url)
        End With
        rate.Open()
        Dim am As Integer = cmd.ExecuteScalar
        If am &gt; 0 Then
            result = True
        Else : result = False
        End If
        rate.Close()
        Return result
    End Function
&lt;/pre&gt;
Функция, считающая общее количество голосов для конкретного url:
&lt;pre name="code" class="vb"&gt;
Public Function CurrentVotes(ByVal url As String) As Integer
        Dim con As String = ConfigurationManager.ConnectionStrings("domvtae_comCS").ConnectionString
        Dim rate As New SqlConnection(con)
        Dim sel As String = "SELECT SUM(Votes) FROM rating WHERE (Url = @Url)"
        Dim cmdVotes As New SqlCommand(sel, rate)
        With cmdVotes.Parameters
            .AddWithValue("@Url", url)
        End With
        rate.Open()
        Dim vts As Integer
        If Not cmdVotes.ExecuteScalar Is DBNull.Value Then
            vts = cmdVotes.ExecuteScalar()
        Else : vts = 0
        End If
        rate.Close()
        Return vts
    End Function
&lt;/pre&gt;
Функция считающая общий рейтинг (сумма всех оценок)
&lt;pre name="code" class="vb"&gt;
Public Function CurrentTotal(ByVal url As String) As Integer
        Dim con As String = ConfigurationManager.ConnectionStrings("domvtae_comCS").ConnectionString
        Dim rate As New SqlConnection(con)
        Dim sel As String = "SELECT SUM(Total) FROM rating WHERE (Url = @Url)"
        Dim cmdTotal As New SqlCommand(sel, rate)
        With cmdTotal.Parameters
            .AddWithValue("@Url", url)
        End With
        rate.Open()
        Dim vts As Integer
        If Not cmdTotal.ExecuteScalar Is DBNull.Value Then
            vts = cmdTotal.ExecuteScalar()
        Else : Return vts = 0
        End If
        rate.Close()
        Return vts
    End Function
&lt;/pre&gt;
Вот и все. Примерно по такому же принципу действует код для отображения текущего рейтинга при первой загрузке страницы. У меня для него написан отдельный веб-сервис, но это не принципиально,- вы можете использовать еще одну функцию в том же веб сервисе, объявив ее как веб-метод.</description><link>http://www.blogasp.net/blog/post.aspx?ID=14</link><pubDate>Sun, 12 Jul 2009 12:16:06 GMT</pubDate></item><item><title>Работа с изображениями в ASP.NET. Часть 4.</title><description>&lt;span style="font-style: italic"&gt;Автор: Андрей Шедько&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;
&lt;h2&gt;Вывод изображений из базы данных.&lt;/h2&gt;
В этой части я расскажу о чтении BLOB полей и выводе изображения в поток. Для чтения и вывода изображения из базы данных мы будем использовать httpHandler, который Вы можете добавить в проект через &lt;span style="font-style: italic"&gt;WebSite - Add New Item - GenericHandler&lt;/span&gt;. После этого у Вас появится файл с расширением &lt;span style="font-weight: bold"&gt;.ashx&lt;/span&gt;

&lt;br /&gt;Прежде всего нам придется импортировать некоторые классы для работы с базой данных, изображениями и потоком.
&lt;pre name="code" class="vb"&gt;
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim ID As Integer = HttpContext.Current.Request.QueryString("OfferID")'получаем ID конкретного изображения
        Dim strm As Stream = ShowImage(ID)
        context.Response.ContentType = "image/jpeg"
        Dim img As Bitmap = Drawing.Image.FromStream(strm)
        Dim thumb As Drawing.Image = img.GetThumbnailImage(160, 120, Nothing, IntPtr.Zero)'здесь мы выводим уменьшенное изображение
        Dim mimetype As String = "image/jpeg"
        Dim encoders() As Imaging.ImageCodecInfo
        Dim jpegEncoder As Imaging.ImageCodecInfo = Nothing
        encoders = Imaging.ImageCodecInfo.GetImageEncoders()
        Dim j As Integer
        For j = 0 To encoders.Length - 1 Step j + 1
            If encoders(j).MimeType = mimetype Then
                jpegEncoder = encoders(j)
            End If
        Next
        Dim paramRatio As Imaging.EncoderParameter
        paramRatio = New Imaging.EncoderParameter(Imaging.Encoder.Quality, 100L)
        Dim jpegParams As Imaging.EncoderParameters
        jpegParams = New Imaging.EncoderParameters(1)
        jpegParams.Param(0) = paramRatio
        HttpContext.Current.Response.ContentType = "image/jpeg"'выводим изображение в общий поток
        thumb.Save(HttpContext.Current.Response.OutputStream, jpegEncoder, jpegParams)
        thumb.Dispose()
        img.Dispose()
    End Sub
&lt;/pre&gt;
И теперь функция, которая собственно считывает изображение из базы данных.
&lt;pre name="code" class="vb"&gt;
Public Function ShowImage(ByVal ID As Integer) As Stream
        Dim conn As String = ConfigurationManager.ConnectionStrings("your_siteCS").ConnectionString
        Dim connection As SqlConnection = New SqlConnection(conn)
        Dim sql As String = "SELECT Pic FROM pictures WHERE (OfferID = @OfferID AND ID IS NOT NULL)"
        Dim cmd As SqlCommand = New SqlCommand(sql, connection)
        cmd.CommandType = Data.CommandType.Text
        cmd.Parameters.AddWithValue("@OfferID", ID)
        connection.Open()
        If Not cmd.ExecuteScalar Is DBNull.Value Then
            Dim img As Object = cmd.ExecuteScalar()
            Return New MemoryStream(CType(img, Byte()))
        Else : Return Nothing
        End If
        connection.Close()
    End Function
&lt;/pre&gt;
Как видите наш код выводит уменьшенное изображение, но конечно же Вы можете немного упростить код для вывода изображения его оригинального размера. Собственно класс Bitmap обладает достаточно широкой функциональностью для работы с изображениями, если Вы захотите поэкспериментировать с этим кодом.</description><link>http://www.blogasp.net/blog/post.aspx?ID=12</link><pubDate>Mon, 22 Jun 2009 11:09:49 GMT</pubDate></item><item><title>Работа с изображениями в ASP.NET. Часть 3.</title><description>&lt;span style="font-style: italic"&gt;Автор: Андрей Шедько.&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;
&lt;h2&gt;Чтение изображений и сохранение их в базе данных.&lt;/h2&gt;
Во второй части мы рассмотрели способ сохранения наших изображений в файловой системе сервера. Теперь же рассмотрим вопрос сохранения изображений в базе данных.&lt;br /&gt;Все современные СУБД поддерживают большие двоичные объекты (&lt;span style="font-weight: bold"&gt;BLOB&lt;/span&gt; - binary large objects). Мы создадим таблицу, аналогичную той, что мы использовали во второй части статьи, но изменим некоторые ее поля. В частности нам больше не нужны поля Path и Url, так как изображений будут извлекаться с помощью &lt;span style="font-weight: bold"&gt;httpHandler&lt;/span&gt; и добавим поле Pic, имеющее тип данных &lt;span style="font-weight: bold"&gt;image&lt;/span&gt;.&lt;br /&gt;
&lt;pre name="code" class="sql"&gt;
USE [somedatabasename] 
GO
******&amp;nbsp;Object:Table [dbo].[gallery] Script Date:&amp;nbsp;06/12/2009&amp;nbsp;14:00:25&amp;nbsp;******&amp;nbsp; 
SET ANSI_NULL ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[gallery]
[ID][int]IDENTITY(1,1) NOT NULL
[Description] [nvarchar](200) NULL
[Category] [nvarchar](20) NULL
[Pic] [image] NULL 
ON PRIMARY
GO
&lt;/pre&gt;&lt;br /&gt;Добавим к этому код, который будет считывать изображение и сохранять его в виде бинарного объекта в базе данных. Он мало отличается от кода во второй части, но обратите внимание на функцию, которая возвращает массив байтов для записи в BLOB поле типа image.
&lt;pre name="code" class="vb"&gt;
Protected Sub btnUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUpload.Click
        Try
            If fu1.HasFile Then
                Dim fileOK As Boolean = False
                Dim fileExtension As String
                fileExtension = System.IO.Path.GetExtension(fu1.FileName).ToLower()
                Dim allowedExtensions As String() = {".jpg", ".jpeg", ".png", ".gif"}
                For i As Integer = 0 To allowedExtensions.Length - 1
                    If fileExtension = allowedExtensions(i) Then
                        fileOK = True
                    End If
                Next
                If fileOK = True Then
                    Dim picSize As Integer = fu1.PostedFile.ContentLength
                    Dim insPic As New SqlCommand("INSERT INTO pictures (Pic, Category, Description) VALUES (@Pic, @Category, @Description)", sale)
                    Dim pics As SqlParameter = insPic.Parameters.Add("@Pic", Data.SqlDbType.Image)
                    pics.Value = GetPhotoByte(fu1.PostedFile.InputStream, picSize)
                    Dim cat As SqlParameter = insPic.Parameters.Add("@Category", Data.SqlDbType.NVarChar, 20)
                    cat.Value = ddlCategories.SelectedItem.Value
                    Dim desc As SqlParameter = insPic.Parameters.Add("@Description", Data.SqlDbType.NVarChar, 200)
                    desc.Value = tbDesc.Text.Trim
                    sale.Open()
                    insPic.ExecuteNonQuery()
                    sale.Close()
                    insPic.Dispose()
                Else : Response.Write("File didn't specified!")
                End If
            End If
        Catch ex As Exception
            Session("bug") = "Error was raised. Please send to tech support: Error at " &amp; Request.RawUrl &amp; ". Exception:" &amp; ex.Message
            Response.Redirect("../contact.aspx")
        End Try
        Finalize()
    End Sub
&lt;/pre&gt;
&lt;br /&gt;А теперь один из самых важных моментов - функция для считывания изображения в виде массива байт.
&lt;pre name="code" class="vb"&gt;
Private Function GetPhotoByte(ByVal fs As Stream, ByVal size As Integer) As Byte()
        Dim img As Byte() = New Byte(size - 1) {}
        fs.Read(img, 0, size)
        If img.Length &lt;&gt; size Then
            Return Nothing
        Else
            Return img
        End If
        fs.Close()
    End Function
&lt;/pre&gt;&lt;br /&gt;В последующих частях я расскажу о выводе изображений из базы данных,  а так же об использовании плагина jQuery LightBox plugin для вывода изображений из файловой системы.</description><link>http://www.blogasp.net/blog/post.aspx?ID=9</link><pubDate>Tue, 16 Jun 2009 17:21:42 GMT</pubDate></item><item><title>Работа с изображениями в ASP.NET. Часть 2.</title><description>Автор: Андрей Шедько.&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;&lt;h2&gt;Сохранение изображений в файловой системе.&lt;/h2&gt;
Сначала продемонстрирую поход к сохранению файлов изображений в файловой системе, как немного более простой. Пример взят из моего проекта - административная панель сайта для добавления изображений в фотогалерею.&lt;br /&gt;Для начала создадим таблицу в базе данных, куда буду записываться данные о сохраненном в файловой системе сервера файле изображения.
&lt;pre name="code" class="sql"&gt;
USE [somedatabasename]
GO
****** Object:Table [dbo].gallery] Script Date: 06/12/2009 14:00:25 ******
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[gallery](
[ID] [int] IDENTITY(1,1) NOT NULL
[Path] [nvarchar](500) NULL
[Description] [nvarchar](200) NULL
[Category] [nvarchar](20) NULL
[Url] [nvarchar](500) NULL
ON [PRIMARY]
GO
&lt;/pre&gt;
[Path] - сюда будет записываться физический путь к файлу изображения. [Description] - описание изображения. [Category] - категория, к которой относится изображение. [Url] - ссылка на изображение. 
Часть веб-формы, отвечающей за загрузку изображения.
&lt;pre name="code" class="html"&gt;
&lt;h2&gt;Добавить фото в галерею&lt;/h2&gt;
&lt;asp:DropDownList ID="ddlCategories" runat="server"&gt;
&lt;asp:ListItem Value=""&gt;Выберите категорию&lt;/asp:ListItem&gt;
&lt;asp:ListItem Value="Bangkok"&gt;Бангкок&lt;/asp:ListItem&gt;
&lt;asp:ListItem Value="Pattaya"&gt;Паттайя&lt;/asp:ListItem&gt;
&lt;asp:ListItem Value="Phuket"&gt;Пхукет&lt;/asp:ListItem&gt;
&lt;asp:ListItem Value="Samui"&gt;Самуи&lt;/asp:ListItem&gt; 
&lt;asp:ListItem Value="KohChang"&gt;Ко Чанг&lt;/asp:ListItem&gt;
&lt;asp:ListItem Value="HuaHin"&gt;Хуа Хин&lt;/asp:ListItem&gt;
&lt;/asp:DropDownList&gt;
&lt;asp:Label ID="lblInfo" runat="server"&gt;
&lt;/asp:Label&gt;
Загрузить фото в галерею
&lt;asp:FileUpload ID="fu1" runat="server" / &gt;
Описание фотографии
&lt;asp:TextBox ID="tbDescPic" runat="server" &gt;
&lt;/asp:TextBox&gt;
&lt;asp:LinkButton ID="lbFileUpload" runat="server"&gt;Загрузить&lt;/asp:LinkButton&gt;
&lt;br /&gt;&lt;/pre&gt;
А вот так будет выглядеть обработчик нажатия на кнопку загрузки:
&lt;pre name="code" class="vb"&gt;
Protected Sub btnLoad_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLoad.Click
Try
If fu1.HasFile Then
Dim fileOK As Boolean = False
Dim fileExtension As String
'Проверяем имеет ли файл разрешенное расширение. Тут можно было бы добавить JavaScript alert в случае если файл запрещен к загрузке.
fileExtension = System.IO.Path.GetExtension(fu1.FileName).ToLower()
Dim allowedExtensions As String() = {".jpg", ".jpeg", ".png", ".gif"}
For i As Integer = 0 To allowedExtensions.Length - 1
If fileExtension = allowedExtensions(i) Then
fileOK = True
End If
Next
If fileOK = True Then
'Указываем категорию, к которой принадлежит фотография
Dim p As String = ddlCategories.SelectedItem.Value
'Проверяем наличие директории, в которой хотим сохранить файл.
If Not System.IO.Directory.Exists(Server.MapPath("~\gallery\") &amp; p) Then
Directory.CreateDirectory(Server.MapPath("~\gallery\") &amp; p) 
End If
Dim path As String = Server.MapPath("~\gallery\") + p + "\" + fu1.PostedFile.FileName
Dim url As String = "http://www.yoursite.com/gallery/" + p + "/" + fu1.PostedFile.FileName
'Сохраняем файл на сервере
fu1.PostedFile.SaveAs(path)
Dim con As String = ConfigurationManager.ConnectionStrings("someCS").ConnectionString
Dim mess As New SqlConnection(con)
Dim insPic As New SqlCommand("INSERT INTO gallery ([Category], [Description], [Path], [Url]) VALUES (@Category, @Description, @Path, @Url)", mess)
With insPic.Parameters
.AddWithValue("@Category", p)
.AddWithValue("@Description", tbDescPic.Text)
.AddWithValue("@Path", path)
.AddWithValue("@Url", url)
End With
mess.Open()
insPic.ExecuteNonQuery()
mess.Close()
insPic.Dispose()
tbDescPic.Text = Nothing
Response.Write("Фото добавлено!")
End If
Else : Response.Write("Файл не выбран!")
End If
Catch ex As Exception
Session("bug") = "Error was raised. Please send to tech support: Error at " &amp; Request.RawUrl &amp; ". Exception:" &amp; ex.Message
Response.Redirect("../contact.aspx")
End Try
Finalize()
End Sub
&lt;/pre&gt;
В следующей части я опишу чтение и сохранение файла изображения в базе данных.</description><link>http://www.blogasp.net/blog/post.aspx?ID=8</link><pubDate>Fri, 12 Jun 2009 14:16:44 GMT</pubDate></item><item><title>Работа с изображениями в ASP.NET. Часть 1.</title><description>&lt;span style="font-style: italic"&gt;Автор: Андрей Шедько.&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;
&lt;h1&gt;Содержание.&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;Где лучше хранить изображения?&lt;/li&gt;&lt;li&gt;Сохранение изображений в файловой системе.&lt;/li&gt;&lt;li&gt;Сохранение изображений в базе данных.&lt;/li&gt;&lt;li&gt;Вывод изображений из базы.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Часть 1. Где лучше хранить изображения.&lt;/h2&gt;
Ответ на этот вопрос не может быть однозначным, так как у каждого разработчика имеются как личные предложения, так и ограничения наложенные например тарифом хостинга вашего проекта. В частности, один из проектов у меня был размещен хостинге, имеющем всего лишь 100МБ использования &lt;span style="font-weight: bold"&gt;MS SQL Server&lt;/span&gt;, что сразу же убирало у меня возможность хранить изображения, которых было много, в базе данных.
Кроме того, после того, как я столкнулся с миром браузерной интерактивности, открытым для меня &lt;span style="font-weight: bold"&gt;jQuery&lt;/span&gt;, сразу же встал вопрос о выводе изображений с помощью плагина &lt;span style="font-weight: bold"&gt;jQuery LightBox plugin&lt;/span&gt;, который сразу же придавал любому сайту вид сайта 2.0.

&lt;br /&gt;В частности известный автор &lt;span style="font-style: italic"&gt;Дино Эспозито&lt;/span&gt; пишет по этому поводу: "Так стоит ли хранить изображения&amp;nbsp; в базе данных? Если вам нужно часто их редактировать, я предлагаю хранить их на жестком диске сервера. Тот же совет я дам и в случае, если изображения очень велики (имеют размер порядка сотен мегабайтов). Если же они используются главным образом для чтения и притом невелики, следует подумать о том, что бы хранить их в базе данных".&lt;br /&gt;В следующих частях этой статьи я постараюсь проиллюстрировать оба подхода.</description><link>http://www.blogasp.net/blog/post.aspx?ID=7</link><pubDate>Fri, 12 Jun 2009 13:51:36 GMT</pubDate></item><item><title>Вызов обновления UpdatePanel через JavaScript</title><description>&lt;span style="font-style: italic"&gt;Автор: Дейв Уорд&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;Я обратил внимание на многочисленные дискуссии, относительно способов обновления UpdatePanel на стороне клиента. Конечно, это просто сделать на стороне сервера просто вызвав метод UpdatePanel.Update(). Однако наиболее распространенные решения для для обновления UpdatePanel на клиентской стороне вызывают ощущение неправильности.&lt;br /&gt;Многие посоветуют Вам использовать скрытый контрол Button внутри панели, который управляется через Button.Click() или использовать триггеры UpdatePanel. Хотя все это работает, меня не оставляло ощущение неуклюжести этих способов.
&lt;h2&gt;Ищем лучший путь.&lt;/h2&gt;Вот слегка модифицированная версия UpdatePanel DateTime, с которой мы будем экспериментировать.
&lt;pre name="code" class="html"&gt;
&lt;asp:ScriptManager ID="ScriptManager1" runat="server" /&gt;
&lt;div id="Container"&gt;
&lt;asp:UpdatePanel runat="server" ID="UpdatePanel1" OnLoad="UpdatePanel1_Load"&gt;
&lt;ContentTemplate&gt;
&lt;asp:Label runat="server" ID="Label1" /&gt;
&lt;/ContentTemplate&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
&lt;pre name="code" class="vb"&gt;
Protected Sub UpdatePanel1_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Label1.Text = DateTime.Now.ToString();
End Sub
&lt;/pre&gt;
Каждый раз при загрузке или постбеке лейбл на АпдейтПанель будет показывать текущие дату-время.
&lt;h2&gt;Не надо боятся __doPostBack()!&lt;/h2&gt;К счастью, имеется легкий способ триггеринга в самой UpdatePanel - __doPostBack(). Так как это событие вызывает асинхронный триггер UpdatePanel, фреймфорк ASP.NET AJAX отложит постбек и вызовет частичное обновление UpdatePanel. С целью демонстрации добавим событие OnClick в div:
&lt;pre name="code" class="html"&gt;
&lt;div id="Container" onclick="__doPostBack('UpdatePanel1', '');"&gt;&lt;/pre&gt;
Сейчас клик будет вызывать частичное обновление страницы и лейбл будет содержать обновленное значение дата-время.&lt;br /&gt;Вы можете справедливо заметить, что существует метод _doPostBack в PageRequestManager. По большей части он работает так же как __doPostBack, однако выполняется лучше так как доходит по полного постбека при недоступности ASP.NET AJAX. Вероятность того, что ASP.NET AJAX фреймворк останется без изменений невелика, в то время как __doPostBack вряд ли исчезнет в будущем.</description><link>http://www.blogasp.net/blog/post.aspx?ID=6</link><pubDate>Wed, 10 Jun 2009 18:22:58 GMT</pubDate></item><item><title>3 причины для использования Google jQuery</title><description>
&lt;span style="font-style: italic"&gt;Автор: Дейв Уорд.&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px" /&gt;
Я часто нахожу код подобный этому на публичных сайтах, использующих &lt;span style="font-weight: bold"&gt;jQuery&lt;/span&gt;: &lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;script type="text/javascript" src="/js/jQuery.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
Если вы делаете так на сайте, открытом для публичного доступа, вы поступаете неправильно. Вместо этого лучше использовать &lt;a target="_blank" href="http://code.google.com/apis/ajaxlibs/"&gt;&lt;span style="font-weight: bold"&gt;Google Ajax&lt;/span&gt; библиотеки&lt;/a&gt; и сеть дата центров Google, отвечающих за доставку контента пользователям. Поступая так, вы получаете 3 преимущества:  
быстрая загрузка контента, увеличение параллелизма, улучшенное&amp;nbsp; кеширование.&lt;br /&gt;
&lt;h2&gt;Ускоренная загрузка контента.&lt;/h2&gt;
CDN (Content Delivery Network) - сеть доставки контента. Отвечает за доставку вашего статического контента пользователю через сеть серверов по всему миру, что означает скорейшую загрузку файла пользователю с ближайшего к нему сервера.&lt;br /&gt;Это означает, что пользователь, расположенный дальше от вашего сервера получит ответ на свой запрос быстрее, чем если бы вы заставляли его получать ответ вашего сервера.&lt;br /&gt;
&lt;h2&gt;Увеличение параллелизма.&lt;/h2&gt;
Что бы избежать излишней загрузки серверов, многие браузеры ограничивают количество соединений и в зависимости от браузера, этот лимит может доходить до всего лишь &lt;span style="font-weight: bold"&gt;двух соединений&lt;/span&gt;. Таким образом использование CDN позволяет передать больше контента за одно соединение. &lt;br /&gt;
&lt;h2&gt;Улучшенное кеширование.&lt;/h2&gt;

Одно из наибольших преимуществ использования CDN заключается в том, пользователям &lt;span style="font-weight: bold"&gt;вообще не нужно загружать jQuery&lt;/span&gt;.
Не важно как настроена ваша политика кеширования - пользователю придется загружать копию jQuery как минимум один раз и в кеше могут хранится десятки копий этой библиотеки и все равно они буду проигнорированы при первом посещении вашего сайта. С другой стороны, если браузер видит многочисленные запросы к одному и тому же файлу, хранящемуся в CDN Google, серверы Google не только вернут ответ 304, но и кешируют этот файл на срок до года. Это означает, что если пользователь посетит даже сотню сайтов, использующих туже версию &lt;span style="font-weight: bold"&gt;jQuery&lt;/span&gt;, библиотека будет 
загружена лишь однажды.
&lt;h2&gt;Как использовать CDN?&lt;/h2&gt;
Здесь есть 2 варианта.  
Первый вариант, предлагаемый Google, предполагает использование такого метода:&lt;pre name="code" class="jscript"&gt;&amp;lt;script type="text/javascript" src="http://www.google.com/jsapi"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript"&amp;gt;
google.load("jquery", "1.3.2");
google.setOnLoadCallback(function()"&amp;gt;{здесь ваш код}&amp;lt;/script&amp;gt;&lt;/pre&gt;
Тут вроде бы все правильно, но есть сомнения в его производительности: &lt;br /&gt;&lt;h2&gt;&lt;img src="http://encosia.com/blog/wp-content/uploads/2008/12/jsapi-long-load.jpg" alt="" style="vertical-align: middle" /&gt;&lt;/h2&gt;На первый взгляд разница совсем небольшая, однако она накапливается, к тому же если можно ускорить загрузку хотя бы некоторой части, почем нет?&lt;br /&gt;Поэтому оптимальным представляется другой метод, так же поддерживаемый Google:&lt;br /&gt;&lt;pre name="code" class="jscript"&gt;&amp;lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript"&amp;gt;
$(document).ready(function(){тут ваш код});
&amp;lt;/script&amp;gt;
&lt;/pre&gt;</description><link>http://www.blogasp.net/blog/post.aspx?ID=5</link><pubDate>Sun, 07 Jun 2009 13:57:32 GMT</pubDate></item></channel></rss>