Archive

Archive for March 9th, 2010

Data structures: Finger Tree (Part 1)

March 9th, 2010 No comments

Data structures: Finger Tree (Part 1)

Categories: Uncategorized Tags:

Автоматизация подписки на рассылку FeedBurner. Часть 3

March 9th, 2010 No comments

Заключительная часть трилогии о том, как взять feedburner’овскую капчу, заставить пользователя ввести её и подписать его на рассылку feedburner.

Часть 1, Часть 2

В этой статье разберем серверную часть программы – php-скрипт, задача которого обратиться к сервису feedburner, получить капчу, передать пользователю, принять расшифровку капчи от пользователя и передать feedburner. Я использовал ZendFramework, но в основном по мелочи.

Итак, весь скрипт состоит из двух больших блоков. Первый – для случая, когда мы только получаем капчу, второй – для случая, когда пользователь её уже расшифровал.

Когда мы обращаемся к фидбернеру в первый раз отрабатывает следующий скрипт:

$client = new Zend_Http_Client(/* здесь должна идти строка с адресом рассылки, которую генерирует feedburner */);
$client->setParameterPost(array(
	        'loc'  => 'ru_RU',
	        'uri'   => /* данные вашей рассылки */,
	        'email' => /* данные вашей рассылки */,
	    ));
$resp = $client->request('POST');	// выполняем POST запрос
$headers = $resp->getHeaders();
 
// меняем относительные пути на полные
$response =  str_replace('captcha?','http://feedburner.google.com/fb/a/captcha?', $resp);
$response =  str_replace('="/fb','="http://feedburner.google.com/fb', $response);
 
// В ответ на наш запрос feedburner генерирует форму
// для заполнения с рядом скрытых (hidden) полей.
// Значение этих полей нам нужно достать и отправить
// обратно фидбернеру при следующем обращении
// Здесь я опушу большую часть однотипных действий
$pos1 = strpos($response, 'action="');
$action = substr($response, $pos1 + 8);
$pos11 = strpos($action, '"');
$action = substr($action, 0, $pos11);
 
$pos1 = strpos($response, 'input type="hidden" name="uri"');
$uri = substr($response, $pos1 + 38);
$pos11 = strpos($uri, '"');
$uri = substr($uri, 0, $pos11);

А далее нам остается только сформировать собственный кусок кода HTML, который AJAX вернет клиенту:

<form>
	<input type="hidden" id="fbaction" name="fbaction" value=""/>
	<input type="hidden" id="fburi" name="fburi" value=""/>
	<input type="hidden" id="fbemail" name="fbemail" value=""/>
	<input type="hidden" id="fbtoken" name="fbtoken" value=""/>
	<input type="hidden" id="fbcookie" name="fbcookie" value=""/>
 
</form>

$action, $uri, $email, $token – то, что мы достали из кода, сгенерированного фидбернером. $headers[‘Set-cookie’] – куки которые, установил фидбернер, их также нужно передать.

А теперь рассмотрим действия, когда пользователь ввел капчу, которую предложил нам фидбернер и отправил данные в наш серверный скрипт.

// клиент для HTTP-запросов
$client = new Zend_Http_Client($action);
// устанавливаем параметры, которые получили в прошлый
// раз от фидбернера
$client->setParameterPost(array(
		'loc'  => 'ru_RU',
	        'token'  => $_GET['token'],
	        'uri'   => $_GET['uri'],
	        'captcha'   => $_GET['captcha'],
	        'email' => $_GET['email']
	    ));
// не забываем добавить куки
$cookie = Zend_Http_Cookie::fromString($_GET['cookie']);
$client->setCookie($cookie);
// делаем POST запрос к фидбернеру
$response = $client->request('POST');

Вот и все. В $response у нас попадет ответ от фидбернера. Он скажет, что, либо регистрация прошла успешно, либо мы неправильно ввели капчу, либо плохой e-mail и т.п. Я ничего лучше не придумал, как проверять полученный текст на наличие каких-то ключевых слов. Это, в общем-то, тривиальная задача.

С миру по нитке #28

March 9th, 2010 No comments

Программирование How works automatic assembly versioning
Принцип, по которому формируется автоматический номер версии сборки. Оказывается это все-таки особое представление текущего времени и даты.
Creating x.509 certificates with Pluralsight self-cert
Создаем self-signed X.509-сертификат программно.
60+ .NET libraries every developer should know about.
Справочник по библиотекам, способным облегчить жизнь .Net-разработчика. Все основные вроде есть.
System.Uri FAQ
Неплохой обзор некоторых подводных камней, проявляющихся при работе с классом System.Uri.
10 заповедей для программистов
Как говорится, ППКС.
Сеть ASP.NET: UpdatePanel and Master Pages
Определяем обновление компонента UpdatePanel.
The Kayak Framework: An easy way to speak HTTP with .NET
Веб-сервер для ASP.NET. Использование IIS не всегда возможно и оправдано, тут то и вступают в дело небольшие самописные обработчики.
Improving CSS With .LESS
Занятные трюки для уменьшения объема CSS-скриптов, что самое приятное, производятся автоматически.
Redirect from Http to Https in ASP.NET
Включение SSL только для нужных страниц сайта.
Discover which Control Raised a PostBack
Определяем контрол, вызвавший отправку формы.
Базы данных SQL SERVER – Performance Comparison – INSERT TOP (N) INTO Table – Using Top with INSERT
Особенности использования оператора TOP при вставке в базу данных результатов выполнения SELECT-а.
Multiple Active Result Sets (MARS – ADO.NET 2.0)
Малоизвестная фича ADO.NET 2.0 и выше – возможность иметь несколько активных запросов для одного соединения бд.
SharePoint Threads and Sharepoint
Немного об особенностях использования потоков в портальных приложениях.

Categories: Uncategorized Tags:

Создание внебраузерных Silverlight приложений. Часть 2.

March 9th, 2010 No comments

Создание внебраузерных Silverlight приложений. Часть 1. Содержание Обновление внебраузерных приложений
Определение наличия сетевого соединения
Архитектура внебраузерных приложений
Отладка внебраузерных приложений
Совместное использование кода и сборок в Silverlight и .NET
Обновление внебраузерных Silverlight приложений В платформу Silverlight встроен асинхронный механизм обновления внебраузерных приложений. Разработчик ответственен за то, когда будет проверяться наличие обновлений для его приложения, а загрузка и установка происходят автоматически. Что требуется от разработчика. Загрузить новую версию .xap файла Silverlight приложения на сервер.
При запуске внебраузерного приложения или в любой другой момент проверить наличие обновлений.
После окончания проверки Silverlight скачает новую версию приложения, которая будет установлена автоматически при следующем запуске. Разработчик может обработать событие окончания проверки и, например, показать пользователю сообщение о необходимости перезапуска приложения.
Давайте добавим возможность обновления в существующее внебраузерное приложение. Откроем C# код страницы App.xaml. И в конструкторе класса «App» подпишемся на событие «CheckAndDownloadUpdateCompleted». this.CheckAndDownloadUpdateCompleted +=
new CheckAndDownloadUpdateCompletedEventHandler(App_CheckAndDownloadUpdateCompleted);
Данное событие окончания проверки на наличие обновлений в случае успеха срабатывает только после физической закачки новой версии на компьютер пользователя. К сожалению, нет возможности спросить у пользователя, хочет ли он скачивать и устанавливать найденное обновление. Так как в следующий раз при запуске приложения пользователь уже будет работать с новой его версией, в обработчике события «CheckAndDownloadUpdateCompleted» уведомим пользователя об этом.void App_CheckAndDownloadUpdateCompleted(object sender,
CheckAndDownloadUpdateCompletedEventArgs e)
{
if (e.UpdateAvailable)
{
MessageBox.Show("Доступно обновление. " +
"Перезапустите приложение для использования новой
версии.");
}
else if (e.Error != null && e.Error is PlatformNotSupportedException)
{
MessageBox.Show("Доступно обновление, " +
"но требуется более новая версия Silverlight.");
}
}
В реальных внебраузерных приложениях вместо MessageBox лучше использовать оповещения или какое-либо другое решение. После того как мы подписались на событие, надо собственно инициировать проверку на наличие обновлений. Нет ничего проще. Добавим следующий код в функцию «Application_Startup» класса «App». this.CheckAndDownloadUpdateAsync();
Из других классов получить текущий экземпляр класса «App» можно через свойство Application.Current. Проверка происходит асинхронно, а от разработчика больше ничего не требуется. Полный код конструктора класса «App» теперь выглядит следующим образом. public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;

this.CheckAndDownloadUpdateCompleted +=
new CheckAndDownloadUpdateCompletedEventHandler(App_CheckAndDownloadUpdateCompleted);

InitializeComponent();
}
Как видите, изменения незначительны. Как и в случае с функцией «Application_Startup», полный код которой также не должен вызвать у Вас удивления. private void Application_Startup(object sender, StartupEventArgs e)
{
this.CheckAndDownloadUpdateAsync();
this.RootVisual = new MainPage();
}
Хорошей практикой является добавление кода, проверяющего наличие обновлений, в каждое создаваемое внебраузерное приложение. Ведь без этого для использования новой версии пользователю придётся удалить старую и установить приложение заново. Определение наличия сетевого соединения Ещё одной часто возникающей задачей является определение наличия сетевого соединения. Ведь если у нас нет доступа в сеть, поведение приложения может коренным образом меняться, а часть его функциональности и вовсе оказаться недоступной. Для того чтобы просто проверить наличие сетевого соединения достаточно вызвать статическую функцию GetIsNetworkAvailable класса NetworkInterface. NetworkInterface.GetIsNetworkAvailable();
Давайте добавим в элемент LayoutRoot на странице MainPage.xaml текстовый блок, куда будем выводить информацию о сетевом соединении. <TextBlock x:Name="tbNetwork" VerticalAlignment="Top"
HorizontalAlignment="Center" FontSize="25"/>
Также напишем функцию, которая будет собственно изменять текст в текстовом блоке. void CheckNetwork()
{
if (NetworkInterface.GetIsNetworkAvailable())
{
tbNetwork.Text = "Сеть доступна";
tbNetwork.Foreground = new SolidColorBrush(Colors.Green);
}
else
{
tbNetwork.Text = "Сеть не доступна";
tbNetwork.Foreground = new SolidColorBrush(Colors.Red);
}
}
Отлично, функция у нас есть. Но когда её вызывать? Если вызвать её один раз при загрузке приложения, то мы не узнаем об изменениях, происходящих с сетевым соединением в процессе работы приложения. К счастью мы можем подписаться на событие NetworkAddressChanged класса NetworkChange, которое происходит при изменении сетевого адреса компьютера, а значит и при исчезновении/появлении сетевого соединения. В обработчике события NetworkChange вызовем функцию CheckNetwork. Кроме того вызовем функцию CheckNetwork в конструкторе класса MainPage (В листинге не приведён код предыдущих примеров). public MainPage()
{
InitializeComponent();

CheckNetwork();
NetworkChange.NetworkAddressChanged += (sender, e) => CheckNetwork();
}
Теперь запустите приложение в браузере или вне его, в условиях, когда сетевое соединение доступно. Вы увидите зелёный текст, сообщающий об этом. Теперь отключите сетевой адаптер, можете выдернуть кабель или сделать другие действия для обеспечения недоступности сети. Надпись сменится автоматически. Чего мы и добивались. Архитектура внебраузерных Silverlight приложений Разрабатывая внебраузерные Silverlight приложения полезно знать, что конкретно выполняется на компьютере у пользователя, где это хранится, а также, куда собственно инсталлируются внебраузерные приложения. Как разработчик Вы создаёте .xap файл Silverlight приложения. Очевидно, что выполняться он не может. Давайте зайдём в свойства ярлыка любого установленного внебраузерного Silverlight приложения. Можно увидеть, что на самом деле запускается файл «sllauncher.exe», расположенный в папке «C:\Program Files\Microsoft Silverlight» или «C:\Program Files (x86)\Microsoft Silverlight» на 64 битных платформах. Ему передаётся Id внебраузерного Silverlight приложения. В данном случае это «2923737553.localhost». Sllauncher.exe при запуске ищет в папке внебраузерных приложений приложение с нужным Id и запускает его внутри своего окна. Папка, куда устанавливаются внебраузерные Silverlight приложения своя для каждого пользователя. Перейдите в директорию «C:\Users\__ИМЯ_ПОЛЬЗОВАТЕЛЯ__\AppData\LocalLow\Microsoft\Silverlight», только учтите, что папка «AppData» является скрытой. Внутри директории «Silverlight» находятся две поддиректории: «is» – место для изолированных хранилищ, а также «OutOfBrowser» – место для размещения внебраузерных приложений. Внутри каждой папки внебраузерного Silverlight приложения находятся несколько файлов, необходимых для его работы. На самом деле было бы не совсем верно утверждать, что при работе внебраузерных Silverlight приложений браузер не используется, так как в окне внебраузерного приложения размещается самый настоящий Internet Explorer, в котором уже выполняется Silverlight. С помощью программы Spy++ это легко увидеть. В первом случае, это видно на рисунке, Silverlight приложение работает в браузере. Во втором случае оно работает вне его. Можно заметить, что везде присутствует «Internet Explorer_Server». Другое дело, что в случае с внебраузерными приложениями мы его не замечаем и не можем запустить в нём что-то отличное от нашего Silverlight приложения. Отладка внебраузерных приложений Мы увидели много интересных возможностей внебраузерных Silverlight приложений, научились создавать такие приложения и узнали, как они работают. Всё это, конечно, хорошо, но на данный момент может быть не совсем очевиден механизм их отладки. Ведь, отлаживая Silverlight приложения в браузере, доступа к специфическим внебраузерным возможностям нет. Поэтому хорошим решением кажется присоединение отладчика к процессу «sllauncher.exe», в котором, как мы увидели ранее, и работают внебраузерные приложения. Но данное решение не позволяет отлаживать код, выполняемый при загрузке внебраузерного Silverlight приложения. Вероятно, должен быть способ лучше. Далее я такой способ и опишу. Предположим, что Silverlight приложение создано, настроено для работы вне браузера и хостится в проекте Web приложения. Если проект Web приложения не является стартовым проектом (запускаемым при нажатии F5 в Visual Studio), сделайте его таковым.
Запустите проект.
Установите внебраузерное Silverlight приложение.
После установки внебраузерное приложение запустится. Закройте его и остановите отладку в Visual Studio.
Сделайте проект Silverlight приложения стартовым. Для этого нажмите правой кнопкой мыши на имени проекта в окне «Solution Explorer» и выберите пункт «Set as StartUp Project».
После этого в том же контекстном меню проекта Silverlight приложения выберите пункт «Properties».
В открывшемся диалоге свойств проекта перейдите на вкладку «Debug». И установите для «Start Action» значение «Installed out-of-browser application». В выпадающем списке выберите, скорее всего, единственный пункт, а именно имя установленного внебраузерного приложения.

Всё, можно сохранить изменения, и поставить точку останова в нужном месте Silverlight приложения.
Нажмите F5. Silverlight приложение сразу запустится вне браузера. Отладчик будет присоединён автоматически.

Совместное использование кода и сборок в Silverlight и .NET Если Вы создаёте Silverlight и WPF версию какого-либо приложения, может потребоваться использовать одни и те же сборки в обеих версиях. Или же один и тот же код должен работать как на сервере, так и на Silverlight клиенте. Вариантов, почему это может быть нужно, множество. В Silverlight присутствует возможность создать сборки, которые можно подключить и в обычных .NET приложениях. Серьёзным ограничением является то, что такие сборки могут использовать только общий для Silverlight и .NET API. Сразу хочется отметить, что пользовательский интерфейс не является порируемым из-за отличий между Silverlight и WPF. Но существуют пять общих ключевых сборок, доступных для использования на обеих платформах. Вот они. mscorlib
System
System.Core
System.ComponentModel.Composition
Microsoft.VisualBasic
Данные сборки являются базовыми и поддерживают только основные сценарии работы, но это лучше, чем отсутствие возможности портирования сборок как таковой. Также надо учитывать, что есть возможность использовать Silverlight сборки в .NET, но не наоборот. Это связано с тем, что Silverlight является подмножеством .NET, а код, созданный для подмножества некоторого API с большей долей вероятности будет работать и в версии с большими возможностями. Давайте создадим новый проект типа «Silverlight Class Library». Добавим в данный проект класс «SharedClass». public class SharedClass
{
private string _text;
public string Text
{
get
{
return _text;
}
}
public SharedClass(string text)
{
_text = String.Format("***{0}***", text);
}
}
Мы можем собрать проект и подключить получившуюся сборку в любое .NET 4.0 или Silverlight приложение. Из .NET приложения получится работать только с кодом, использующим классы пяти портируемых сборок. Класс «SharedClass» ничего лишнего не использует, поэтому создадим консольное .NET 4.0 приложение, подключим нужную сборку и протестируем работу класса «SharedClass». static void Main(string[] args)
{
SharedClass sharedClass = new SharedClass("Hello Silverlight!");
Console.WriteLine(sharedClass.Text);
}
Бывают ситуации, когда возможностей, предлагаемых портируемыми сборками оказывается недостаточно. Тогда стоит воспользоваться более сложными приёмами. Например, в .NET и Silverlight приложениях использовать одни и те же файлы исходного кода. А для кода, зависимого от платформы применять условную компиляцию. Рассмотрим это на примере. Откроем существующее Silverlight приложение и щёлкнем правой кнопкой мыши на названии решения («Solution …») в окне «Solution Explorer». В контекстном меню выберем Add -> New Solution Folder. Назовём папку «SharedCode» и добавим в неё файл с C# кодом класса «SharedClass», рассмотренным ранее. Добавим ссылку на данный файл в проект Silverlight приложения и проект ASP.NET приложения. Для этого в контекстном меню соответствующего проекта нажмём Add -> Existing Item… , выберем файл «SharedClass.cs», а вместо «Add» выберем «Add As Link». Теперь ссылка на файл присутствует в обоих проектах. Соответственно в обоих проектах можно использовать класс «SharedClass». Более того, можно добавить в данный класс код, различный для каждой платформы с помощью условной компиляции. В свойствах проекта Silverlight приложения и на вкладке «Build» определён параметр «Conditional compilation symbols». Его значение равно «SILVERLIGHT». Данный символ и будет использоваться в условии при компиляции. Добавим в класс функцию «ShowText». В случае использования данной функции в Silverlight приложении будет показано сообщение с текстом, а в ASP.NET текст будет выведен на страницу. public void ShowText()
{
#if SILVERLIGHT
System.Windows.MessageBox.Show(_text);
#else
System.Web.HttpContext.Current.Response.Write( _text);
#endif
}
Это происходи потому, что данная функция компилируется по-разному для .NET и Silverlight приложений. Более того, уже не важно классы каких сборок используются. Главное, чтобы компиляция происходила корректно.

Categories: Uncategorized Tags:

ASP.NET MVC: Http Handler умер, да здравствует FileResult

March 9th, 2010 No comments

Если вы разрабатывали приложения в ASP.NET MVC, то достаточно хорошо знакомы с классом ActionResult. ActionResult самый распространенный тип объектов возвращаемый действием. Когда разрабатывается MVC приложения, большую часть времени вы используете именно ActionResult класс.
На предыдущей неделе, я работал над своим open source проектом WeBlog, я создавал HTTP Handler для обработки изображений. Я начал использовать HTTP Handler для изображений, потому что нуждался в механизме предотвращения дополнительной нагрузке(hotlinking). Единственным минусом в использовании HTTP Handler – уродливые URL адреса. Читать полностью

Categories: Uncategorized Tags:

Используем ASP.NET 4 определение браузера в ASP.NET 3.5

March 9th, 2010 No comments

Перевод статьи "Use ASP.NET 4 Browser Definitions with ASP.NET 3.5".
Мы обновили файлы определения браузера в ASP.NET 4, теперь они содержат информацию о таких браузерах и устройствах, как Google Chrome и iPhone. Вы можете использовать файлы определения браузера и в более ранних версиях ASP.NET, например в ASP.NET 3.5. Обновленные файлы определения информации и инструкции по установке могут быть найдены тут. Изменения в файлах определения браузера могут вызвать проблемы обратной совместимости, если вы обновляете ASP.NET 3.5 проект до ASP.NET 4. Если у вас возникли такие проблемы, то у вас есть возможность загрузить старый файлы определения браузера в ASP.NET приложение.
Читать полностью

Categories: Uncategorized Tags: