Поиск по блогу

Showing posts with label web-программирование. Show all posts
Showing posts with label web-программирование. Show all posts

Sunday, October 4, 2015

Включение error_reporting в .htaccess

Для начала простой рецепт: 

Для включения вывода ошибок php в файле .htaccess необходимо добавить строку
php_value error_reporting 7
php_flag display_errors On
Эта запись соответствует включению вывода ошибок уровня «E_ERROR | E_WARNING | E_PARSE»
Для отключения вывода ошибок, включенного в php.ini используйте
php_value error_reporting 0
php_flag display_errors O

Теперь подробнее:

В интернете гуляет множество рецептов, предлагающих устанавливать вывод ошибок с помощью конструкции
php_value error_reporting “E_ALL & ~E_NOTICE”
но во многих случаях это не работает.
Для установки уровня сообщений об ошибках php требуется указать битовую маску, которая в десятичном представлении является целым положительным числом. Когда в php-коде в параметрах функции error_reporting мы указываем значение, например вида E_ERROR | E_WARNING | E_PARSE, на самом деле мы передаем результат действий над именованными константами php, имеющими значение типа int. С помощью документации легко убедиться что функция error_reporting в качестве параметра ожидает получить отнюдь не строку, а целое числовое значение.
Давайте разберемся, что это за зверь такой — битовая маска.
Если открыть список констант php, ответственных за установку уровня вывода ошибок, то можно заметить, что числовое значение каждой из них является «круглым» в двоичном представлении. То есть в двоичном виде константы будут выглядеть в виде одной единицы в старшем разряде и нескольких нулей после нее. Например:
КонстантаДесятичное представлениеДвоичное представление
E_ERROR1
  1
E_WARNING2
 10
E_PARSE4
100
Таким образом: выражение E_ERROR | E_WARNING | E_PARSE даст результат 111 в двоичном формате или 7 в десятичном. Эту-то семерку мы и подставили в директиву htaccess php_value error_reporting 7.
Зная значения констант можно легко варьировать уровень вывода ошибок, при этом нет необходимости переводить числа из десятичного представления в двоичное и обратно вручную. Нам поможет стандартный калькулятор Windows (замечу, что калькулятор, встроенный в (x)Ubuntu имеет схожие возможности). Запустим калькулятор и переведем его в режим «Программист» с помощью меню «Вид» как это показано на рисунке.
Переключение калькулятора в режим "Программист"

Теперь допустим, что мы хотим видеть сообщения об ошибках, но не хотим видеть никаких предупреждений (например мы работаем с каким-то старым php-кодом, использующим множество устаревших конструкций).
Убедимся, что калькулятор находится в десятичном режиме ввода (радио-баттон в положении «Dec») и будем последовательно вводить значения констант, отвечающих за вывод ошибок применяя к ним операцию «Or».
Органы управления калькулятора в режиме "Программист"
Константы, ответственные за предупреждения мы пропустим.
Таким образом мы выполним
1 Or 4 Or 16 Or 64 Or 256 Or 4096
что соответствует E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR. После нажатия равно мы получим 4437, что будет соответствовать битовой маске
1000101010101
В файле htaccess мы пропишем php_value error_reporting 4437 и многочисленные предупреждения не будут нам мешать, в то же время мы будем получать сообщения обо всех ошибках, приводящих к падению скрипта.

Thursday, September 24, 2015

Плагин Microkid’s Related Posts - создание списка похожих статей на WordPress

К CMS WordPress разработано как минимум несколько плагинов, позволяющих выводить к каждому посту список похожих по теме заметок. Одним из самых популярных плагинов является Related Posts, который осуществляет поиск статей в автоматическом режиме по заранее заданным параметрам (тегам, категориям). Однако иногда возникает необходимость вывести в списке похожих постов какие-то определенные статьи, выбранные вами вручную. Вот здесь-то на помощь и приходит плагин Microkid’s Related Posts.
Загрузить версию данного плагина, понимающую русский язык при поиске по ключевым словам, можно отсюда - http://www.wordpressplugins.ru/download/microkids-related-posts.zip. Оригинальная английская версия с русскими словами работать не будет. После установки и активации можно пройти в настройки, которые располагаются в пункте «Related Posts» админки блога.
Добавить сам модуль с выводом списка похожих постов можно несколькими способами. Самый часто используемый способ – вставка php-кода с функцией плагина напрямую в код шаблона single.php. Вставлять следует именно в то место, в котором вы хотите видеть данный список (как правило, модуль выводится перед комментариями). Сам код вставки выглядит следующим образом
<?php if( function_exists("MRP_show_related_posts") )
MRP_show_related_posts();
?>
Чтобы подобрать список похожих постов для каждой конкретной заметки, зайдите на страницу редактирования этой заметки и воспользуйтесь пунктом «Искать записи». Укажите ключевое слово / фразу и выберите, где именно следует его искать – в заголовке, контенте или везде. Рядом с каждым найденным постом будет показана стрелочка, нажав на которую, вы добавите его в список.
Кроме того, список похожих постов можно добавить на блог посредством виджета, который называется «Связанные записи». В настройках этого виджета можно указать тип связанных записей (посты или статичные страницы), параметры отображения, миниатюру и некоторые другие вещи. В большинстве случаев для вывода списка похожих постов используют прямой код вставка плагина, а не виджет, так как виджет отображается в верхней части страницы, а это неудобно для пользователей.
Что касается внешнего вида блога со ссылками на похожие статьи, то по умолчанию он выводится в виде маркированного списка. Изменить внешний вид можно в файле style.css используемой темы, добавив туда нужные правила для таких селекторов, как #related-posts-MRP_all (сам блок), #related-posts-MRP_all li (элемент списка статей), #related-posts-MRP_all li a (ссылка в элементе списка). К примеру, можно изменить размер и тип шрифта, фоновый цвет и т.д.

Sunday, April 6, 2014

Верстка вложенного вертикального меню

 Как правило меню такого типа делают с помощью вложенных друг в друга маркированных списков, устанавливая элементам списка различные значения фона в зависимоти от того, какой пункт меню в данный момент активен. Единственное, что при этом нужно учитывать - высота актианого пункта меню верхнего уровня растягивается на высоту отображаемых вложенных пунктов. Впрочем это легко решается добавлением дескриптроа "top" к свойству background.
Попробуем сверстать вот такое меню:
Для верстики заголовка и низа меню воспользуемся методом, который я уже описывал ранее.   Границы меню и его пунктов сделаем с помощью border.
Изображения, которые нам понадобятся:
  • - Картинки для верстки заголовка меню;
  • - Картинки для верстки подвала меню;
  • - Картинки маркеров пунктов меню;
HTML-код в итоге получится такой:
<html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
 <div class="menu-module">
  <!-- Заголовок меню -->
  <img alt="" src="images/lbar.png" class="lbar top_bar">
  <img alt="" src="images/rbar.png" class="rbar top_bar">
  <h3 class="mbar menu-header">Навигация</h3>
  <!-- Список пунктов меню -->
  <ul class="nav menu">
   <li class="item"><a href="#">Главная</a></li>
   <li class="item active deeper parent">
    <a href="#">DataLife Engine</a>
    <ul class="nav-child unstyled small">
     <li class="item"><a href="#">Хаки</a></li>
     <li class="item"><a href="#">Модули</a></li>
     <li class="item current active"><a href="#">Релизы</a></li>
     <li class="item"><a href="#">Баги/Фиксы</a></li>
    </ul></li>
   <li class="item parent"><a href="#">Invision Power Board</a></li>
   <li class="item parent"><a href="#">vBulletin</a></li>
   <li class="item parent"><a href="#">phpBB</a></li>
  </ul>
  <!-- Подвал меню -->
  <img alt="" src="images/bottom_left_menu_bar.png" class="lbar bottom_bar">
  <img alt="" src="images/bottom_right_menu_bar.png" class="rbar bottom_bar">
  <div class="mbar menu_bottom"></div>
 </div>
</body>
</html> 
Поскольку нижняя граница последнего пункта меню у нас задается в подвале, то при написании CSS-стилей для остальных пунктов будем отображать только верхнюю границу. Также необходимо учесть, что верхняя граница не нужна под активным пунктом меню верхнего уровня, для этого используем стиль ".menu-module .menu li:FIRST-CHILD". В итоге CSS-стили получатся следующие:
/* --- Общие настройки обтекания блоков ---*/
.lbar {
 display: block; float: left;
}
.rbar {
 display: block; float: right;
}
.mbar {
 margin-top: 0px; margin-bottom: 0px;
}
.clr {
 clear:both;
}
/* --- Заголовок меню --- */
.menu-module {
 max-width: 300px;
 margin: 100px;
}
.menu-module .top_bar {
 width: 8px; height: 34px;
}
.menu-header {
 height: 34px;
 background: url('../images/mbar.png');
 margin: 0px 8px; padding-left: 20px;
 font-size: 12px; color: #fff; line-height: 34px;
}
/* --- Пункты меню --- */
.menu-module ul {
 list-style: none;
}
.menu-module .menu {
 border-top: 1px solid #ccc; border-left: 1px solid #ccc; border-right: 1px solid #ccc;
}
.menu-module .menu li {
 border-top: 1px solid #ccc;
}
.menu-module .menu li:FIRST-CHILD {
 border-top: none;
}
.menu-module .menu a {
 height: 25px; margin-left: 10px; padding-left: 10px;
 display: block;
 background: url('../images/inactivebullet.png') left no-repeat;
 line-height: 25px;
}
.menu-module .menu .active {
 background: url('../images/active_background.png') top repeat-x;
}
.menu-module .menu .active a {
 margin-left: 30px; padding-left: 10px;
 background: url('../images/activebullet.png') left no-repeat;
 color: #fff;
}
.menu-module .menu ul .active {
 background: none;
}
.menu-module .menu ul a {
 background: none !important;
 color: #000 !important;
}
.menu-module .menu ul li.current a {
 background: url('../images/currentbullet.png') left no-repeat !important;
}
/* --- Подвал меню --- */
.menu-module .bottom_bar {
 width: 11px; height: 11px;
}
.menu_bottom {
 height: 11px;
 background: url('../images/bottom_medium_menu_bar.png');
 margin: 0px 11px;
}

Проверка доменов на занятость, проверка списком, подбор доменов по ключевым словам, поиск похожих доменов  Перейти

Friday, January 24, 2014

Плагин Sphinx Search для Joomla 2.5

Sphinx - это поисковая система, позволяющая быстро индексировать таблицы баз данных и производить полнотекстовый поиск по ним. В основе работы системы лежит принцип индексации базы альтернативным приложением.
Приложение Sphinx устанавливается в систему. Все настройки для него прописываются в конфигурационном файле sphinx.conf, в числе которых присутствуют параметры соединения с базой данных, запросы к таблицам для индексирования, каталоги для хранения индексов и прочее. Полную документацию для настройки sphinx.conf можно найти здесь.
Существуют решения включающие поиск Sphinx для CMS Битрикс, Wordpress и других. Также мне удалось найти плагин Sphinx для Joomla, но тут вышла накладка. Несмотря на то, что на странице проекта заявлена поддержка Joomla 2.5, реально он работает только в версии 1.5.
Немного поковырявшись в коде я переделал его под 2.5. После установки вы получаете пять плагинов для поиска по различным компонентам Joomla и компонент административной части для настройки. Активировав поисковые плагины Sphinx, можно деактивировать стандартный поиск Joomla.
К сожалению у меня не было достаточно больших таблиц для того, что бы оценить преимущества Sphinx в скорости полнотекстового поиска. Буду рад любым замечаниям и предложениям по доработке.
Скачать SpinxSearch_Joomla2.5 (нажмите Ctrl+S на открывшейся странице)
VPS-сервера (OpenVZ / Xen) от 102 руб. в месяц  Подробнее...
А также хостинг сайтов на Joomla от 119 руб. в месяц  Подробнее...

Sunday, October 28, 2012

Exp4j Java-библиотека для разбора формул.

Если вам в Java-программе когда либо понадобится производить разбор формул вида «(A + B) /C» не обязательно избретать собственный велосипед. За вас уже все сделали. Некий Фрэнк Ассег (Frank Asseg) из западной Германии написал небольшую библиотеку весом всего 40 KB, без каких либо дополнительных зависимостей. Она реализует изобретенный Эдсгером Дейкстрой так называемый «Алгоритм сортировочной станции», благодаря чему способна обрабатывать запись математические выражения и функции, записанные в форме, понятной человеку.
Далее приведены примеры использования этой библиотеки.

Вычисление простого выражения:

Calculable calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
        .withVariable("x", varX)
        .withVariable("y", varY)
        .build()
double result1=calc.calculate();

Вычисляемое выражение может содержать переменные. Имена переменных могут состоять состоять из символов цифр и символа подчеркивания. При этом они должны начинаться с буквы или символа подчеркивания. Например следующие имена переменных являются правильными: varX, _x1, _var_X_1, а имя переменной 1_var_x не правильное так как не начинается ни с цифры, ни с символа подчеркивания.
Метод withVariable() позволяет определить единственную переменную в выражении:

Calculable calc = new ExpressionBuilder("x * y - 2")
        .withVariableNames("x","y")
        .build();
calc.setVariable("x",1);
calc.setVariable("y",2);
assertTrue(calc.calculate()==0);

С помощью метода withVariableNames() можно определить сразу несколько переменных за один раз:

Calculable calc = new ExpressionBuilder("x * y - 2")
        .withVariable("x",1);
        .withVariable("y",2);
        .build();
assertTrue(calc.calculate()==0);

Библиотека также поддерживает определение польовательских функций. Для этого необходимо реализовать метод applyFunction(double[] values):

CustomFunction fooFunc = new CustomFunction("foo") {
    public double applyFunction(double[] values) {
                return values[0]*Math.E;
        }
};
double varX=12d;
Calculable calc = new ExpressionBuilder("foo(x)")
        .withCustomFunction(fooFunc)
        .withVariable("x",varX)
        .build();
assertTrue(calc.calculate() == Math.E * varX);

Можно определить и функцию с принимющую больше одного аргумента например max(a, b, c) с помощью конструктора CustomFunction(String name, int argc), где 'argc' означает количество аргументов принимаемых функцией аргументов:

CustomFunction custom1 = new CustomFunction("max",3) {
    @Override
    public double applyFunction(double[] values) {
        double max=values[0];
        for (int i=1;i max) {
                max=values[i];
            }
        }
        return max;
    }
};
double varX=Math.E;
Calculable calc = new ExpressionBuilder("max(log(x),sin(x),x)")
        .withVariable("x", varX)
        .withCustomFunction(custom1)
        .build();
assertTrue(varX == calc.calculate());

Пользовательские операторы.

Вы можете расширить абстрактный класс CustomOperator, что бы определить собственную операцию с помощью одного из следующих символов '!,#,§,$,&,;,:,~,<,>,|,='. Учтите, что добавление в CustomOperator исползованный ранее символ переопределяет любую существующую операцию, включая встроенную. Возможно переопределить даже операцию '+'. CustomOperator принимает до 4-х аргументов:


  • Символ, используемый для операции (один из !,#,§,$,&,;,:,~,<,>,|,=);
  • Оператор левоассоциативный (т.е. воздейсвтует на число слева от себя);
  • Приоритет операции;
  • Количество операндов в операции (1 или 2);


CustomOperator factorial = new CustomOperator('!', true, 6, 1) {
        @Override
    double applyOperation(double[] values) {
        double tmp = 1d;
        int steps = 1;
        while (steps < values[0]) {
                tmp = tmp * (++steps);
        }
        return tmp;
    }
};
Calculable calc = new ExpressionBuilder("11!").withOperation(factorial).build();
assertTrue(39916800d == calc.calculate());


Библиотека поддерживает встроенные операторы:

  • Сложение '2 + 2';
  • Вычитание '2 — 2';
  • Умножение '2 * 2';
  • Деление '2 / 2';
  • Возведение в степень '2 ^ 2';
  • Унарный минус или плюс (знаковый оператор) '+2 - (-2)';
  • Остаток от деления '2 % 2';

Приоритет унарного минуса

Приоритет унарных операций при возведении в степень может быть установлен с помощью системного свойства "exp4j.unary.precedence.high". Свойство можно установить с помощью System.setProperty(PROPERTY_UNARY_HIGH_PRECEDENCE, "false"), что бы изменить вычисление такого выражения как -3 ^ 2 с варианта (-3) ^ 2 на -(3 ^ 2):


String expr = "-3^2";
System.setProperty(ExpressionBuilder.PROPERTY_UNARY_HIGH_PRECEDENCE, "false");
Calculable calc = new ExpressionBuilder(expr).build();
assertTrue(-Math.pow(3, 2) == calc.calculate()); // вычислит '-9'

System.clearProperty(ExpressionBuilder.PROPERTY_UNARY_HIGH_PRECEDENCE);
calc = new ExpressionBuilder(expr).build();
assertTrue(Math.pow(-3,2) == calc.calculate()); // вычислит '9'

Встроенные функции

  • abs: абсолютное значение
  • acos: arc-косинус
  • asin: arc-синус
  • atan: arc-тангенс
  • cbrt: корень кубический
  • ceil: ближайшее верхнее целое
  • cos: косинус
  • cosh: hyper-косинус
  • exp: число Эйлера в степени (e^x)
  • floor: ближайшее нижнее целое
  • log: натуральный логарифм (по основанию e)
  • sin: синус
  • sinh: hyper-синус
  • sqrt: корень квадратный
  • tan: тангенс
  • tanh: hyper-тангенс

Более подробную информацию вы можете найти на официальной странице проекта.

Thursday, January 3, 2008


Использование Automation (ActiveX/Com) объектов в ASP.NET 1)

Иногда мы склонны полагать, что .NET является панацеей от всех наших проблем и что все технологии, используемые до наступления эры .NET должны быть немедленно отправлены в Корзину. Технология, которая в значительной степени страдает от этого непонимания, - ActiveX, также известная как (OLE) или automation COM. Функция CreateObject функция создает COM-объекты и часто используется в классических серверных ASP скриптах для настройки веб-страниц. Это не всегда является наилучшим методом кодирования, но оно работает. Серверные элементы управления ASP.NET и действительно объектно-ориентированный .NET Framework - это огромный шаг вперед. Для решения многих проблем, для которых раньше применялась COM сейчас лучше использовать .NET, но это не означает, что COM больше не существует. Если некоторые из ваших существующих COM классов работают хорошо, то почему вы должны конвертировать их в .NET? Это не то, что COM обещала Вам! Расслабьтесь, существует еще много вещей, которые можно делать при помощи COM в ASP.NET. В этой статье я покажу вам некоторые из достоинств COM, которые она может вам предложить.

COM-ы не вымерли!

Прежде чем погрузиться в .NET разработку я хочу ближе познакомить вас с COM. COM расшифровывается как Объектная Модель Компонентов, которая описывает протокол, разделяющий интерфейс объекта и его реализацию. Интерфейс - это то, как объект выглядит, это декларация его свойств и методов. Реализация - это код, который фактически исполняется, когда метод вызывается или читаются свойства. Пользователь объекта использует COM, чтобы получить описание класса и, таким образом, построить объект этого класса. Пользователь получает COM-интерфейс к объекту. Все методы и свойства могут быть выполнены через этот интерфейс, но сам COM-объект не может быть уничтожен пользователем. COM-объект будет удален сборщиком мусора. Здесь нет ничего необычного, интерфейсы широко используются в .NET. Описание классов это одно из достоинств .NET и в каждой сборке присутствует в виде метаданных. В COM используются библиотеки типов (typelibraries) для описания классов, они довольно часто доступны как ресурсы внутри самого файла библиотеки.

Windows поддерживает множество типов COM-интерфейсов, наиболее часто используемый - это IDispatch интерфейс. В реализации COM-класса этого интерфейса его функционал поддерживает два метода:

  1. Его методы можно вызвать прямо из виртуальной таблицы (vtable) объекта, формат vtable описан в typelibrary этого COM-класса. Компилятор перенаправляет вызовы согласно vtable. Это называется vtable-связыванием, или как говорят сегодня ранним связыванием. (Фактически раннее связывание ссылается на диспетчерские интерфейсы (dispinterfaces), область действия которых ограничена событиями COM).

  2. В интерфейсе есть методы, принимающие название метода или свойства в строковом формате, выполняющие динамический поиск в typelibrary, после чего метод может быть вызван. Интерпретатор скрипта использует эти методы для перенаправления вызовов скрипта методам объекта. Это называется поздним связыванием.

Классические ASP-скрипты используют второй метод для заполнения веб-страниц на сервере. Клиентские скрипты используют позднее связывание для исполнения кода в браузере клиента. Объекты, к которым обращаются с помощью этих IDispatch интерфейсов, часто называют как (OLE) automation объекты. Термин ActiveX когда-то придуманный для всего COM функционала сегодня в основном используется для описания визуальных (ActiveX) элементов управления, к которым обращаются с помощью целого набора различных COM-интерфейсов.

COM идеальный протокол для подключения компонент, созданных с помощью различных средств, он поддерживается всеми основными Windows-языками, например, VB (A), Delphi, C++, VBscript и JavaScript и конечно-же в .NET. В библиотеке классов .NET вы найдете пространство имен System.runtime.interop. Большинство свойств и методов оттуда отвечают за неуправляемые COM-соединения, которые предусматривают создание COM-объектов, а также за передачу данных между этими объектами. COM-объекты не работают в безопасном типе управляемого .NET-кода. Связь между управляемой и неуправляемой частью вполне работоспособна. Распределение данных также называется сортировкой, .NET будет использовать собственный системный сортировщик для сортировки COM-объектов. Иногда можно услышать, что части .NET реализованы с помощью COM. Я бы сказал, что COM и .NET используют одни и те же методы для соединения объектов.

Начнем работу с COM в ASP.NET приложениях. Я построил очень простой automation-сервер. Она называется DemoServer.MyDemo, и он поддерживает один метод, названный MyMethod, принимающий один параметр типа строка и возвращающий эту же строку с префиксом "your server echoes ". Он сделан на Delphi, более подробно о том как это сделать Вы можете найти на www.Gekko-Software.nl/Software.htm

Клиентские Automation-объекты

В ASP.NET приложениях весь код исполняется на IIS-сервере. Код, работающий у клиента может выполнять отдельные функции, такие как проверку наличия какого-либо устройства или открытие пользователем адресной книги и отправку данных на серверную часть приложения. В случае реализации в качестве automation сервера, объекты просматриваемой страницы можно создавать и управлять ими с помощью небольших фрагментов сценария. Поскольку я не очень хорошо знаком с html, я предпочитаю реализовывать все это на C# с веб-страницей с раздельным кодом.

Я буду экспериментировать с простой веб-страницей. Эта страница имеет два элемента TextBox и Button. Это все серверные элементы управления, что означает, что они недоступны на клиентской машине так же как на сервере. TextBox-ы в клиентской форме будут представлены в виде текстового поля ввода. Мой скрипт может считывать и устанавливать их текстовые значения, которые будут доступны на сервере после отправки данных. Первый TextBox используется для ввода строки, которая будет передана automation-объекту, второй TextBox содержит результат вызова функции объекта. Я напишу Jscript функцию, которая создает automation-объект, читает TextBox, взывает метод и обновляет второй TextBox.

function doMySubMit() {

var MyAx;

MyAx = new ActiveXObject("DemoServer.MyDemo");

document.getElementById('TextBox2').value = MyAx.MyMethod(document.getElementById('TextBox1').value);

}


ActiveXObject это Jscript-функция, которая создает новый automation (ActiveX) объект, идентифицируемый с помощью ProgId параметра. В полученном в результате объекте я вызываю MyMethod, передавая ему строку из TextBox1. Результат заносится в TextBox2.

В C # константы будут храниться в классах, как собственно и все остальное. Я создам статический класс, содержащий текст сценария и соответствующие константы:

class MyJScript {
const string
head = "<script language="JavaScript">";
const string
foot = "</script>";
public const string
scriptBlockName = "startup";
public const string
functionName = "doMySubMit()";
public const string
MySubmit =
head +
"function " + functionName + "{" +
"var MyAx;" +
"MyAx = new ActiveXObject("DemoServer.MyDemo");" +
"document.getElementById('TextBox2').value = MyAx.MyMethod(document.getElementById('TextBox1').value);" +
"}" +
foot;
}


Статические классы можно использовать, не создавая объекта. После объявления я могу использовать MyJscript.MySubmit, - константу, содержащую JavaScript-код заключенный теги скрипта.

В событии Page_Load я могу приспособить страницу для своих нужд. Помимо установки контролов, я могу добавить здесь клиентские скрипты. Page.RegisterStartupScript вставляет блок скрипта на страницу. Перед этим Page.IsStartupScriptRegistered проверяет, был ли скрипт уже добавлен на страницу для предотвращения двойной работы. Page.RegisterOnSubmitStatement является гораздо более мощным методом, в котором я могу определить имя функции клиентского скрипта (из моего только-что вставленного блока скрипта), который будет вызываться при отправке формы на сервер. Класс MyJScript предоставляет все параметры, необходимые для этих методов.

private void Page_Load(object sender, System.EventArgs e)

{

// Put user code to initialize the page here

if (! IsStartupScriptRegistered(MyJScript.scriptBlockName))

RegisterStartupScript(MyJScript.scriptBlockName, MyJScript.MySubmit);

RegisterOnSubmitStatement("Mysubmit", MyJScript.functionName);

}


Когда страница отправляется на сервер, на клиенте запускается моя Jscript функция, убедиться в ее работе можно проверив TextBox2. Internet Explorer выдаст предупреждение, что данный код является потенциально опасным. Automation-объекты могут содержать в себе код, которые мог бы изменить, например, пользовательскую адресную книгу или даже отформатировать диски. Если настройки безопасности IE, не слишком низкие, будет выдаваться диалоговое окно с предупреждением.

Чтобы предотвратить появление это окна можно либо изменить настройки безопасности браузера либо подписать ваш ActiveX класс. Первый вариант не следует воспринимать слишком серьезно. Во втором случае вы в конечном итоге приобретете сертификат у такой компании как Verisign, которым можно подписывать ваши automation-классы как надежные. Подписание совсем несложно в .NET, но и для классических automation-классов оно требует достаточно времени и денег.

Серверные Automation-объекты

Большинство классических ASP скриптов выполняются на сервере. Automation-объекты, используемые скриптах выполняют работу (или часть ее) лучше, так как выполнены лучше и по более надежным технологиям. Неизбежные ошибки сценария выявляются слишком поздно, потому что многие ошибки незаметны до тех пор, пока сценарий не начал работать. Кроме того, cкомпилированный код работает быстрее интерпретируемого. С ASP.NET этот "ад сценариев" может быть отправлен в корзину и от многих automation-объектов, которые только генерируют html-код можно с успехом отказаться. Зато остальные automation-классы все еще остаются полезными. Первый вариант состоит в том, чтобы переделать их в .NET, а другой - использования их как есть. Благодаря поддержки automation в .NET последнее несложно сделать.

В solution explorer-е я добавлю ссылку на библиотеку COM, которую я хочу использовать. После нажатия кнопки "Добавить ссылку", в solution explorer-е я щелкаю ярлычок COM и выбираю библиотеку DemoServer. Теперь Visual Studio импортирует typelibrary и сгенерирует классы-обертки для DemoServer automation-класса. В моем проекте теперь есть пространство имен interop.DemoServer, которое содержит MyDemoClass, который реализует интерфейс ImyDemo, которой содержит метод MyMethod.

Я могу использовать automation-класс, как и любой другой класс .NET. По клику на Button2 создается automation-объект и вызывается его метод.

private void Button2_Click(object sender, System.EventArgs e)

{

DemoServer.MyDemoClass axo = new DemoServer.MyDemoClass();

Label1.Text = axo.MyMethod(TextBox1.Text);

}


Вот и все. Весь код исполняется сервере до передачи клиенту в отдельном от веб-страницы файле. Мне доступны все серверные компоненты, в том числе серверные элементы управления, мне больше не требуется TextBox для отображения результата, это сделает Label.

В ASP.NET можно продолжать использовать ваши automation-объекты благодаря тому что .NET Interop позволяет гладко интегрировать automation-объекты внутрь .NET-приложения. Объект запускается у клиента, фактически так же, как и до использования ASP.NET. Клиент не знает, что выполняется .NET, он просто запускает скрипт. ASP.NET предоставляет очень удобную функцию для предоставления сценариев клиентской стороне.

 
Google+