Общие сведения о службах проверки подлинности и приложений профилей ASP.NET AJAX

по Скотт Cate

Скачать в формате PDF

Служба проверки подлинности позволяет пользователям предоставлять учетные данные для получения файла cookie проверки подлинности, а служба шлюза — для разрешения настраиваемых профилей пользователей, предоставляемых ASP.NET. Использование службы проверки подлинности ASP.NET AJAX совместимо со стандартной проверкой подлинности на основе форм ASP.NET, поэтому приложения, использующие проверку подлинности с помощью форм (например, с элементом управления Login), не будут разорваны путем обновления до службы проверки подлинности AJAX.

Введение

В рамках .NET Framework 3,5 корпорация Майкрософт предоставляет возможность обновления в среде с возможностью изменения размеров. доступна не только новая среда разработки, но и усовершенствования новых функций LINQ и других языков. Кроме того, некоторые знакомые функции других наборов инструментов, особенно ASP.NET расширения AJAX, включаются в качестве членов первого класса библиотеки базовых классов .NET Framework. Эти расширения включают в себя множество новых многофункциональных клиентских функций, включая частичную визуализацию страниц без полного обновления страницы, возможность доступа к веб-службам через клиентский сценарий (включая API профилирования ASP.NET) и обширный API на стороне клиента. предназначен для отражения многих схем управления, наблюдаемых в наборе серверных элементов управления ASP.NET.

В этом техническом документе рассматривается реализация и использование служб ASP.NET профилирования и проверки подлинности с помощью форм, так как они доступны в Microsoft ASP.NET AJAX-расширения AJAX делают проверку подлинности форм чрезвычайно простой в поддержке, как она (а также Служба профилирования) предоставляется через скрипт прокси веб-службы. Расширения AJAX также поддерживают пользовательскую проверку подлинности с помощью класса Аусентикатионсервицеманажер.

Этот технический документ основан на выпуске бета-версии 2 Visual Studio 2008 и .NET Framework 3,5. В этом техническом документе также предполагается, что вы будете работать с бета-версией 2 Visual Studio 2008, а не с Visual Web Developer Express, и предоставит пошаговые руководства в соответствии с пользовательским интерфейсом Visual Studio. Некоторые примеры кода могут использовать шаблоны проектов, недоступные в Visual Web Developer Express.

Профили и проверка подлинности

Профили Microsoft ASP.NET и службы проверки подлинности предоставляются системой проверки подлинности форм ASP.NET и являются стандартными компонентами ASP.NET. Расширения AJAX ASP.NET предоставляют скрипту доступ к этим службам через прокси-серверы сценариев, используя довольно простую модель в пространстве имен sys. Services клиентской библиотеки AJAX.

Служба проверки подлинности позволяет пользователям предоставлять учетные данные для получения файла cookie проверки подлинности, а служба шлюза — для разрешения настраиваемых профилей пользователей, предоставляемых ASP.NET. Использование службы проверки подлинности ASP.NET AJAX совместимо со стандартной проверкой подлинности на основе форм ASP.NET, поэтому приложения, использующие проверку подлинности с помощью форм (например, с элементом управления Login), не будут разорваны путем обновления до службы проверки подлинности AJAX.

Служба профиля обеспечивает автоматическую интеграцию и хранение пользовательских данных на основе членства, предоставляемых службой проверки подлинности. Сохраненные данные указываются в файле Web. config, а различные поставщики служб профилирования обработают управление данными. Как и в случае со службой проверки подлинности, служба профиля AJAX совместима со стандартной службой профиля ASP.NET, поэтому страницы, в настоящее время включающие функции службы профиля ASP.NET, не следует разбивать, включая поддержку AJAX.

Включение служб проверки подлинности и профилирования ASP.NET в приложение выходит за рамки этого технического документа. Дополнительные сведения о данном разделе см. в справочной статье библиотеки MSDN Управление пользователями с помощью членства на https://msdn.microsoft.com/library/tw292whz.aspx. ASP.NET также включает служебную программу для автоматической настройки членства с SQL Server, которая является поставщиком службы проверки подлинности по умолчанию для членства ASP.NET. Дополнительные сведения см. в статье ASP.NET SQL Server Registration Tool (ASPNET_регскл. exe) по адресу https://msdn.microsoft.com/library/ms229862(vs.80).aspx.

Использование службы проверки подлинности ASP.NET AJAX

В файле Web. config должна быть включена служба проверки подлинности ASP.NET AJAX:

<system.web.extensions> 
 <scripting>
 <webServices>
 <authenticationService enabled="true" /> 
 </webServices>
 </scripting> 
</system.web.extensions>

Служба проверки подлинности требует включения проверки подлинности ASP.NET Forms и требует включения файлов cookie в клиентском браузере (сценарий не может включить сеанс без файлов cookie, так как сеансы без файлов cookie требуют параметров URL-адреса).

После включения и настройки службы проверки подлинности AJAX клиентский скрипт может сразу же воспользоваться объектом sys. Services. AuthenticationService. В основном клиентский скрипт будет использовать преимущества метода login и свойства isLoggedIn. Существует несколько свойств для предоставления значений по умолчанию для метода входа, что может принимать большое количество параметров.

Элементы sys. Services. AuthenticationService

метод входа:

Метод Login () начинает запрос на проверку подлинности учетных данных пользователя. Этот метод является асинхронным и не блокирует выполнение.

Параметры:

Имя параметра Значение
userName Обязательный элемент. Имя пользователя для проверки подлинности.
password Необязательный (значение по умолчанию — NULL). Пароль пользователя.
Persistent Необязательный (значение по умолчанию — false). Должен ли файл cookie проверки подлинности пользователя сохраняться в сеансах. Если задано значение false, то пользователь выйдет из сеанса, когда браузер закроется, или истечет срок его действия.
redirectUrl Необязательный (значение по умолчанию — NULL). URL-адрес для перенаправления браузера после успешной проверки подлинности. Если этот параметр имеет значение null или является пустой строкой, перенаправление не происходит.
кустоминфо Необязательный (значение по умолчанию — NULL). Этот параметр в настоящее время не используется и зарезервирован для использования в будущем.
логинкомплетедкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при успешном завершении имени входа. Если этот параметр указан, он переопределяет свойство Дефаултлогинкомплетед.
фаиледкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при неудачном входе. Если этот параметр указан, он переопределяет свойство Дефаултфаиледкаллбакк.
userContext Необязательный (значение по умолчанию — NULL). Настраиваемые данные контекста пользователя, которые должны быть переданы функциям обратного вызова.

Return Value (Возвращаемое значение).

Эта функция не включает возвращаемое значение. Однако при завершении вызова этой функции включается ряд поведений:

  • Текущая страница будет либо обновлена, либо изменена, если параметр redirectUrl не имел ни значения NULL, ни пустой строки.
  • Однако если параметр имел значение null или является пустой строкой, вызывается параметр loginCompletedCallback или свойство defaultLoginCompletedCallback.
  • В случае сбоя вызова веб-службы вызывается параметр failedCallback свойства defaultFailedCallback.

Метод Logout:

Метод Logout () удаляет файл cookie учетных данных и записывает текущего пользователя из веб-приложения.

Параметры:

Имя параметра Значение
redirectUrl Необязательный (значение по умолчанию — NULL). URL-адрес для перенаправления браузера после успешной проверки подлинности. Если этот параметр имеет значение null или является пустой строкой, перенаправление не происходит.
логауткомплетедкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая после успешного завершения выхода. Если этот параметр указан, он переопределяет свойство Дефаултлогауткомплетед.
фаиледкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при неудачном входе. Если этот параметр указан, он переопределяет свойство Дефаултфаиледкаллбакк.
userContext Необязательный (значение по умолчанию — NULL). Настраиваемые данные контекста пользователя, которые должны быть переданы функциям обратного вызова.

Return Value (Возвращаемое значение).

Эта функция не включает возвращаемое значение. Однако при завершении вызова этой функции включается ряд поведений:

  • Текущая страница будет либо обновлена, либо изменена, если параметр redirectUrl не имел ни значения NULL, ни пустой строки.
  • Однако если параметр имел значение null или является пустой строкой, вызывается параметр logoutCompletedCallback или свойство defaultLogoutCompletedCallback.
  • В случае сбоя вызова веб-службы вызывается параметр failedCallback свойства defaultFailedCallback.

Свойство Дефаултфаиледкаллбакк (Get, Set):

Это свойство указывает функцию, которая должна вызываться, если происходит сбой связи с веб-службой. Он должен получить делегат (или ссылку на функцию).

Ссылка на функцию, заданная этим свойством, должна иметь следующую сигнатуру:

function AuthenticationFailureCallback(error, userContext, methodName);

Параметры:

Имя параметра Значение
ошибка Указывает сведения об ошибке.
userContext Указывает сведения о контексте пользователя, предоставляемые при вызове функции входа или выхода.
methodName Имя вызывающего метода.

Свойство Дефаултлогинкомплетедкаллбакк (Get, Set):

Это свойство задает функцию, которая должна вызываться при завершении вызова веб-службы входа. Он должен получить делегат (или ссылку на функцию).

Ссылка на функцию, заданная этим свойством, должна иметь следующую сигнатуру:

function AuthenticationLoginCompletedCallback(validCredentials, userContext, methodName);

Параметры:

Имя параметра Значение
валидкредентиалс Указывает, предоставил ли пользователь действительные учетные данные. true, если пользователь успешно вошел в систему; в противном случае false.
userContext Указывает сведения о контексте пользователя, предоставляемые при вызове функции входа.
methodName Имя вызывающего метода.

Свойство Дефаултлогауткомплетедкаллбакк (Get, Set):

Это свойство задает функцию, которая должна вызываться после завершения вызова веб-службы Logout. Он должен получить делегат (или ссылку на функцию).

Ссылка на функцию, заданная этим свойством, должна иметь следующую сигнатуру:

function AuthenticationLogoutCompletedCallback(result, userContext, methodName);

Параметры:

Имя параметра Значение
набор по Этот параметр всегда будет null. он зарезервирован для использования в будущем.
userContext Указывает сведения о контексте пользователя, предоставляемые при вызове функции входа.
methodName Имя вызывающего метода.

свойство с ведением журнала (Get):

Это свойство возвращает текущее состояние проверки подлинности пользователя. Он задается объектом ScriptManager во время запроса страницы.

Это свойство возвращает значение, true, если пользователь в данный момент вошел в систему. в противном случае возвращается false.

Свойство пути (Get, Set):

Это свойство программно определяет расположение веб-службы проверки подлинности. Его можно использовать для переопределения поставщика проверки подлинности по умолчанию, а также декларативного набора в свойстве Path дочернего узла AuthenticationService элемента управления ScriptManager (Дополнительные сведения см. в разделе Использование пользовательского поставщика службы проверки подлинности. раздел приведен ниже.)

Обратите внимание, что расположение службы проверки подлинности по умолчанию не меняется. Однако ASP.NET AJAX позволяет указать расположение веб-службы, которая предоставляет тот же интерфейс класса, что и прокси-сервер службы проверки подлинности ASP.NET AJAX.

Обратите внимание, что для этого свойства не должно быть задано значение, направляющее запрос скрипта к текущему сайту. Поскольку текущее приложение не получит учетные данные для проверки подлинности, оно было бы бесполезным. Кроме того, базовая технология AJAX не должна разносить межсайтовые запросы и может вызвать исключение безопасности в клиентском браузере.

Это свойство является объектом String, представляющим путь к веб-службе проверки подлинности.

Свойство времени ожидания (Get, Set):

Это свойство определяет период ожидания для службы проверки подлинности перед тем, как предположить, что запрос на вход не выполнен. Если время ожидания истекает при ожидании завершения вызова, вызывается обратный вызов, не являющийся запросом, и вызов не будет завершен.

Это свойство является объектом Number, представляющим количество миллисекунд ожидания результатов от службы проверки подлинности.

Пример кода: вход в службу проверки подлинности

Следующая разметка представляет собой пример страницы ASP.NET с простым вызовом скрипта для методов login и Logout класса AuthenticationService.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head runat="server">
 <title>Login Example</title>
 <script type="text/javascript">
 function Login()
 {
 var userTextbox = $get("txtUser");
 var passTextbox = $get("txtPassword");
 Sys.Services.AuthenticationService.login(userTextbox.value, 
 passTextbox.value, false, null, null, LoginServiceCompleted, 
 LoginServiceFailed, "Context Info");
 }
 function Logout()
 {
 Sys.Services.AuthenticationService.logout(null, LogoutServiceCompleted, 
 LoginServiceFailed, "Context Info");
 }
 function LoginServiceFailed(error, userContext, methodName)
 {
 alert('There was an error with the authentication service:\n\n' + error);
 }
 function LoginServiceCompleted(validCredentials, userContext, methodName)
 {
 if (validCredentials)
 {
 alert('Great! You successfully logged in.');
 }
 else
 {
 alert('Oops! You gave us bad credentials!');
 }
 }
 function LogoutServiceCompleted(result, userContext, methodName)
 {
 alert('You have been logged out from the web site.');
 }
 </script>
 </head>
 <body>
 <form id="form1" runat="server">
 <asp:ScriptManager ID="ScriptManager1" runat="server" 
 EnableScriptLocalization="true">
 </asp:ScriptManager>
 <div>
 <asp:TextBox ID="txtUser" runat="Server"></asp:TextBox>
 <br />
 <asp:TextBox ID="txtPassword" runat="Server" TextMode="Password"/>
 <br />
 <asp:Button Text="Log in" ID="btnLogin" runat="server" 
 OnClientClick="Login(); return false;" />
 </div>
 </form>
 </body>
</html>

Доступ к данным профилирования ASP.NET через AJAX

Служба профилирования ASP.NET также предоставляется через расширения AJAX для ASP.NET. Так как служба профилирования ASP.NET предоставляет обширный детализированный API-интерфейс для хранения и извлечения пользовательских данных, это может быть отличным средством повышения производительности.

Служба профиля должна быть включена в файле Web. config; по умолчанию он не используется. Для этого убедитесь, что для дочернего элемента profileService включен параметр = true в файле Web. config и что вы указали, какие свойства можно считывать или записывать следующим образом:

<system.web.extensions>
 <scripting>
 <webServices>
 <profileService enabled="true"
 readAccessProperties= Name,Address,BackgroundColor 
 writeAccessProperties= BackgroundColor />
 </webServices>
 </scripting>
</system.web.extensions>

Необходимо также настроить службу профиля. Несмотря на то, что настройка службы профилирования выходит за рамки этого документа, стоит отметить, что группы, как определено в параметрах конфигурации профиля, будут доступны как подсвойства имени группы. Например, при указании следующего раздела профиля:

<profile enabled="true">
 <properties>
 <add name="Name" type="System.String"/>
 <group name="Address">
 <add name="Line1" type="System.String"/>
 <add name="Line2" type="System.String"/>
 <add name="City" type="System.String"/>
 <add name="State" type="System.String"/>
 <add name="Zip" type="System.String"/>
 </group>
 <add name="BackgroundColor" type="System.Drawing.Color"/>
 </properties>
</profile>

Клиентский сценарий сможет получить доступ к имени, адресу, строка1, Address. Строка2, Address. город, Address. штат, Address. zip и BackgroundColor в качестве свойств поля свойств класса ProfileService.

После настройки службы профилирования AJAX она будет немедленно доступна на страницах. Однако он должен быть загружен один раз перед использованием.

Элементы sys. Services. ProfileService

поле свойств:

Поле свойства предоставляет все настроенные данные профиля как дочерние свойства, на которые может ссылаться соглашение "точка-имя". Свойства, являющиеся дочерними для групп свойств, называются GroupName. PropertyName. В примере конфигурации профиля, приведенном выше, чтобы получить состояние пользователя, можно использовать следующий идентификатор:

Sys.Services.ProfileService.properties.Address.State

метод Load:

Загружает выбранный список или все свойства с сервера.

Параметры:

Имя параметра Значение
propertyNames Необязательный (значение по умолчанию — NULL). Свойства, загружаемые с сервера.
лоадкомплетедкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при завершении загрузки.
фаиледкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при возникновении ошибки.
userContext Необязательный (значение по умолчанию — NULL). Контекстная информация, передаваемая функции обратного вызова.

Функция Load не имеет возвращаемого значения. Если вызов завершился успешно, он вызовет либо параметр loadCompletedCallback, либо свойство defaultLoadCompletedCallback. Если при вызове произошел сбой или истекло время ожидания, будет вызван либо параметр failedCallback, либо свойство defaultFailedCallback.

Если параметр propertyNames не указан, все свойства, настроенные для чтения, извлекаются с сервера.

метод Save:

Метод Save () сохраняет указанный список свойств (или все свойства) в профиле ASP.NET пользователя.

Параметры:

Имя параметра Значение
propertyNames Необязательный (значение по умолчанию — NULL). Свойства, которые необходимо сохранить на сервере.
савекомплетедкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при завершении сохранения.
фаиледкаллбакк Необязательный (значение по умолчанию — NULL). Функция, вызываемая при возникновении ошибки.
userContext Необязательный (значение по умолчанию — NULL). Контекстная информация, передаваемая функции обратного вызова.

Функция Save не имеет возвращаемого значения. Если вызов завершается успешно, он вызывает либо параметр saveCompletedCallback, либо свойство defaultSaveCompletedCallback. Если при вызове произошел сбой или истекло время ожидания, будет вызвано либо свойство failedCallback, либо defaultFailedCallback.

Если параметр propertyNames имеет значение null, все свойства профиля будут отправлены на сервер, и сервер определит, какие свойства можно сохранить, а какие — нет.

Свойство Дефаултфаиледкаллбакк (Get, Set):

Это свойство указывает функцию, которая должна вызываться, если происходит сбой связи с веб-службой. Он должен получить делегат (или ссылку на функцию).

Ссылка на функцию, заданная этим свойством, должна иметь следующую сигнатуру:

function AuthenticationFailureCallback(error, userContext, methodName);

Параметры:

Имя параметра Значение
Ошибка Указывает сведения об ошибке.
userContext Указывает сведения о контексте пользователя, предоставляемые при вызове функции Load или Save.
methodName Имя вызывающего метода.

Свойство Дефаултсавекомплетед (Get, Set):

Это свойство задает функцию, которая должна вызываться после завершения сохранения данных профиля пользователя. Он должен получить делегат (или ссылку на функцию).

Ссылка на функцию, заданная этим свойством, должна иметь следующую сигнатуру:

function ProfileSaveComplete(numPropsSaved, userContext, methodName);

Параметры:

Имя параметра Значение
нумпропссавед Указывает количество сохраненных свойств.
userContext Указывает сведения о контексте пользователя, предоставляемые при вызове функции Load или Save.
methodName Имя вызывающего метода.

Свойство Дефаултлоадкомплетед (Get, Set):

Это свойство задает функцию, которая должна вызываться после завершения загрузки данных профиля пользователя. Он должен получить делегат (или ссылку на функцию).

Ссылка на функцию, заданная этим свойством, должна иметь следующую сигнатуру:

function ProfileLoadComplete(numPropsLoaded, userContext, methodName);

Параметры:

Имя параметра Значение
нумпропслоадед Указывает число загруженных свойств.
userContext Указывает сведения о контексте пользователя, предоставляемые при вызове функции Load или Save.
methodName Имя вызывающего метода.

Свойство пути (Get, Set):

Это свойство программно определяет расположение веб-службы профиля. Его можно использовать для переопределения поставщика службы профиля по умолчанию, а также для декларативного задания в свойстве Path дочернего узла ProfileService элемента управления ScriptManager.

Обратите внимание, что расположение службы профиля по умолчанию не изменяется. Однако ASP.NET AJAX позволяет указать расположение веб-службы, которая предоставляет тот же интерфейс класса, что и прокси-сервер службы проверки подлинности ASP.NET AJAX.

Обратите внимание, что для этого свойства не должно быть задано значение, направляющее запрос скрипта к текущему сайту. Базовая технология AJAX не должна разносить межсайтовые запросы и может вызвать исключение безопасности в клиентском браузере.

Это свойство является объектом String, представляющим путь к веб-службе профиля.

Свойство времени ожидания (Get, Set):

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

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

Пример кода: Загрузка данных профиля при загрузке страницы

Следующий код проверит, прошел ли пользователь проверку подлинности, и если да, то загрузит предпочтительный цвет фона пользователя в качестве страницы.

function Page_Load()
{
 if (Sys.Services.AuthenticationService.get_isLoggedIn())
 {
 Sys.Services.ProfileService.load();
 }
}
function ProfileLoaded(numPropsLoaded, userContext, methodName)
{
 document.documentElement.style.backgroundColor = Sys.Services.ProfileService.properties.BackgroundColor;
}

Использование пользовательского поставщика службы проверки подлинности

Расширения AJAX ASP.NET позволяют создать поставщик службы проверки подлинности пользовательского скрипта, предоставив функциональные возможности через пользовательскую веб-службу. Для использования веб-служба должна предоставлять два метода: Login и Logout. и эти методы должны быть указаны с теми же сигнатурами методов, что и веб-служба проверки подлинности ASP.NET AJAX по умолчанию.

После создания пользовательской веб-службы необходимо указать путь к ней либо декларативно на странице, либо программно в коде, либо с помощью клиентского скрипта.

Чтобы декларативно задать путь:

Чтобы декларативно задать путь, включите дочерний элемент AuthenticationService объекта ScriptManager на странице ASP.NET:

<asp:ScriptManager ID="ScriptManager1" runat="server">
 <AuthenticationService Path="~/AuthService.asmx" />
</asp:ScriptManager>

Чтобы задать путь в коде, выполните следующие действия.

Чтобы задать путь программно, укажите путь через экземпляр диспетчера скриптов:

protected void Page_Load(object sender, EventArgs e)
{
    this.ScriptManager1.AuthenticationService.Path = "~/AuthService.asmx";
}

Чтобы задать путь в скрипте, выполните следующие действия.

Чтобы задать путь программным способом в скрипте, используйте свойство path класса AuthenticationService:

function Login()
{
 var userTextbox = $get("txtUser");
 var passTextbox = $get("txtPassword");
 Sys.Services.AuthenticationService.set_path("./AuthService.asmx");
 Sys.Services.AuthenticationService.login(userTextbox.value, passTextbox.value, false, null, null, LoginServiceCompleted, LoginServiceFailed, "Context Info");
}

Пример веб-службы для пользовательской проверки подлинности

<%@ WebService Language="C#" Class="AuthService" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
[ScriptService]
[WebService]
public class AuthService : WebService
{
 [WebMethod]
 public bool Login(string userName, string password, bool createCookie)
 {
 Session["LoggedInUser"] = userName;
 return true;
 }
 [WebMethod]
 public void Logout()
 {
 Session.Abandon();
 }
}

Сводка

Службы ASP.NET Services, в частности профилирование, членство и службы проверки подлинности, легко предоставляются JavaScript в клиентском браузере. Это позволяет разработчикам легко интегрировать код на стороне клиента с механизмом проверки подлинности без необходимости в зависимости от таких элементов управления, как UpdatePanel, для выполнения тяжелой работы. Данные профиля также можно защитить от клиента, используя параметры веб-конфигурации; по умолчанию данные недоступны, и разработчики должны принять участие в свойствах профиля.

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

Биография

Скотт Cate работал с веб-технологиями Майкрософт с 1997 и является президентом myKB.com (www.myKB.com), где он специализируется на написании приложений ASP.NET на базе знаний, посвященных программным решениям. Скотт может связаться по электронной почте по адресу scott.cate@myKB.com или в блоге по адресу ScottCate.com