Поиск слов при помощи дополнительных операторов. Создание и подготовка базы данных

Every ASP.NET developer needs to be familiar with Page Directives. If you are a beginner and you want to learn about the Page Directives then you can read this article.

So the first question is about Page Directives.

What is a Page Directive?

Basically Page Directives are commands. These commands are used by the compiler when the page is compiled.

How to use the directives in an ASP.NET page

It is not difficult to add a directive to an ASP.NET page. It is simple to add directives to an ASP.NET page. You can write directives in the following format:

<%@%>

See the directive format, it starts with "<%@" and ends with "%>". The best way is to put the directive at the top of your page. But you can put a directive anywhere in a page. One more thing, you can put more than one attribute in a single directive.

Here is the full list of directives:

  • @Page
  • @Master
  • @Control
  • @Import
  • @Implements
  • @Register
  • @Assembly
  • @MasterType
  • @Output Cache
  • @PreviousPageType
  • @Reference

Let"s discuss something about each directive.

When you want to specify the attributes for an ASP.NET page then you need to use @Page Directive. As you know, an ASP.NET page is a very important part of ASP.NET, so this directive is commonly used in ASP.NET.

<%@Page Language="C#" AutoEventWIreup="false" CodeFile="Default.aspx.cs" Inherits="_Default"%>

Now you have some information about @Page Directives. The @Master Directive is quite similar to the @Page Directive. The only difference is that the @master directive is for Master pages. You need to note that, while using the @Master Directive you define the template page"s property. Then any content page can inherit all the properties defined in the Master Page. But there are some properties that are only available in a Master Page.

<%@Master Language="C#" AutoEventWIreup="false" CodeFile="MasterPage1.master.cs" Inherits="MasterPage"%>

@Control

@Control builds ASP.NET user controls. When you use the directive you define the properties to be inherited by the user controls and theses values are assigned to the user controls

<%@Control Language="C#" Explicit="True" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>

As you know you need to define namespaces in your .cs class before using a C# or VB class. So the @Import Directive imports namespaces. This directive supports just a single attribute "namespace" and this attribute takes a string value that specifies the namespace to be imported. One thing you need to note is that the @Import Directive cannot contain more than one attribute/value pair. But you can use multiple lines.

<%@Import Namespace="System.Data"%>

@Implements

The @Implements Directive gets the ASP.NET pages to implement .Net framework interfaces. This directive only supports a single attribute interface.

<%@Implements Interface="System.Web.UI.IValidator"%>

@Register

When you create a user control and you drag that user control onto your page then you will see the @Register directive. This directive registers your user control on the page so that the control can be accessed by the page.

<%@ Register TagPrefix="MayTag Namespace="MyName.MyNameSpace" Assembly="MyAssembly"%>

@Assembly

The @Assembly Directive attaches assemblies to the page or an ASP.NET user control thereby all the assembly classes and interfaces are available to the class. This directive supports the two attributes Name and src. The Name attribute defines the assembly name and the src attribute defines the source of the assembly.

<%@Assembly Name="MyAssembly"%>
<%@Assembly src="MYAssembly.cs">

@MasterType

The @MasterType Directive connects a class name to the ASP.NET page for getting strongly typed references or members contained in the specified Master Page. This directive supports the two attributes Typename and virtualpath. Typename sets the name of the derived class from which to get the strongly typed or reference members and virtualpath sets the location of the page from which these are retrieved.

<%@MasterType VirtualPath="/MasterPage1.master"%>

@output cache

It controls the output caching policies of an ASP.NET page.

<%@ OutputCache Duration ="180" VaryByParam="None"%>
@Previouspagetype

This directive specifies the page from which any cross-page posting originates.

@Reference

This directive declares that another page or user control shout be complied along with the active page or control. This directive supports the single attribute virtualpath. It sets the location of the page or user control from which the active page will be referenced.

<%@Reference VirtualPayh="~/MyControl.ascx"%>

Final Words

I hope you get some knowledge from here. Please comment about how you like this article. Your comments are very valuable for me, because only you will tell me where I am going wrong and what improvements I need to make to write a better article. Please comment and provide your feedback.

Что такое гостевая книга?

Разумеется, здесь речь идет о наиболее типичной гостевой книге. Прежде всего это система, предоставляющая пользователю возможности для ввода текста, выбора оценки того или иного сайта, а также для указания собственных данных (ФИО, e-mail, http и т.д.). Это также система представления данных, введенных различными пользователями, с возможностью навигации, отправки электронных писем авторам сообщений. Возможны и вариации с различными настройками и с контролем нормативности лексики.

Что нам понадобится

Конечно, предполагается, что читатель знаком с основами ASP- и SQL-программирования (знакомства с первыми частями настоящей статьи для этого будет вполне достаточно). Кроме того, нам потребуется Microsoft SQL Server 7.0 или 2000, какой-нибудь HTML- или текстовый редактор (рекомендую использовать Macromedia Dreamweaver UltraDev 4.0) и немного терпения.

Создание и подготовка базы данных

Для организации хранения введенных пользователями данных вам понадобиться одна таблица, где можно завести поля для хранения имени пользователя, его электронного адреса, страны проживания, адреса сайта, IP-адреса, значения оценки пользователем сайта по пятибалльной шкале и т.д:

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

  • Запустите программу-конфигуратор источников данных (Data Sources ODBC) - Start->Settings->Control Panel->Administrative Tools->Data Sources ODBC.
  • Перейдите во вкладку System DSN и создайте новый источник данных, нажав на Add…
  • В появившемся списке драйверов выберите драйвер баз данных - Microsoft SQL Server и нажмите на Next.
  • В строке Data Source Name задайте имя вашей базы данных (в описываемом примере Gustbook - это имя, по которому вы в дальнейшем будете обращаться к ней).
  • В строке Server укажите сервер, к которому будет осуществлено подключение, и нажмите на Next.
  • Выберите режим аутентификации With SQL Server…, задайте имя пользователя и пароль для подключения к SQL-серверу; определите протокол связи с сервером (кнопка Client Configuration - TCP/IP) и два раза нажмите на Next, после чего нажмите на Finish.
  • Вы увидите статистику о проделанных действиях, а для проверки источника данных можете воспользоваться кнопкой Test Data Source.
  • В итоге перед вами появится строка в списке источников данных в вашей системе.

Теперь, когда база данных готова, можно переходить непосредственно к созданию гостевой книги.

Интеграция системы в уже готовый сайт

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

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

Представим себе пример реализации такой таблицы: .

Как видите, здесь присутствуют поля для хранения информации об имени и пароле доступа к режиму настройки системы, о цветах основного фона сообщения пользователей, верхней и нижней рамок (поля Mid_Color, Top_Color, Bot_Color соответственно), о цвете и размере заголовка формы, служащей для ввода пользователем данных (поля Form_Color и FormTitleSize соответственно), о цвете, размере и начертании шрифра текста самого сообщения, информационных полей, а также самих страниц с гостевой книгой (поля MessageFontColor, MessageFontSize, MessageFontFace, InfoFontColor, InfoFontSize, InfoFontFace, PageFontColor, PageFontSize и PageFontFace соответственно), полей-переключателей для включения режима автоматической отправки уведомлений о поступлении новых сообщений по электронной почте ответственному лицу (например, менеджеру или администратору сайта), поля хранения электронного адреса ответственного лица, текста сообщения с благодарностями за оставленное пользователем сообщение, со списком недопустимых слов и переключателем режима их фильтрации (если последний включен, то слова, находящиеся в списке недопустимых, будут автоматически заменяться в тексте сообщения на звездочки и таким образом будет осуществлен контроль за нормативностью лексики текстов сайта).

Развитие системы интеграции гостевой книги подразумевает организацию и Web-интерфейса для настройки всех рассмотренных нами параметров (полей таблицы администрирования).

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

ASP на блюдечке (Часть - 15) – Гостевая книга

Как видите, в первом случае директива о включении странички с гостевой книгой () указана в нужном месте, а во втором случае страничка исходного сайта представлена просто в виде трех последовательно включаемых элементов: начала, странички с гостевой книгой и конца. Использование того или иного способа организации структуры странички вашего сайта - дело вкуса и зависит как от структуры исходного сайта, так и от степени его сложности.

Главная страничка гостевой книги (файл Guest.asp)

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

Для начала напишем несколько функций для работы со строками:

  1. Функцию замены пустой строки на пробел и одинарной кавычки на двойную: <% Function ChkString(string) If string = "" then string = " " ChkString = Replace(string, """, """") End Function %>
  2. Функцию проверки лексики текста сообщения на нормативность. В случае обнаружения совпадений слов со словами из списка недопустимых следует заменять их на звездочки: <% Function ChkBadWords(String2) strBadWords = objRec2("BadWords") bwords = split(strBadWords, "|") For i = 0 to ubound(bwords) String2 = Replace(String2, bwords(i), string(len(bwords(i)),"*"), 1,-1,1) Next ChkBadWords = String2 end function %>
  3. Функцию форматирования текста, введенного пользователем. В случае необходимости (при наличии соответствующего флажка в базе данных) будет проверяться (фильтроваться) текст на предмет нормативности: <% Function FormatStr(String) on Error resume next String = Server.HTMLEncode(String) String2 = Replace(String, CHR(13), "") String2 = Replace(String, CHR(10) & CHR(10), "

    ") String2 = Replace(String, CHR(10), "
    ") If objRec2("BadOn") = True then String2 = ChkBadWords(String2) End if FormatStr = String2 End Function %>

  4. Функцию проверки заполнения полей: <% Function ValidateField(sFieldValue, sFieldType) Valid = True Select Case LCase(sFieldType) Case "name" If Len(sFieldValue) = 0 Then Valid = False Case "message" If Len(sFieldValue) = 0 Then Valid = False End Select ValidateField = Valid End Function %>
  5. Процедуру добавления новых сообщений (обратите внимание на то, каким образом вычисляется IP-адрес компьютера, с которого посланно сообщение):
<% Sub Update strSql = "insert into Messages (Name, Country, Email, URL,IP,Message,Rating) values ("" strSql = StrSql & ChkString(Request.Form("name")) & "", "" strSql = StrSql & ChkString(Request.Form("Country")) & "", "" strSql = StrSql & ChkString(Request.Form("email")) & "", "" strSql = StrSql & ChkString(Request.Form("URL")) & "", "" strSql = StrSql & Request.ServerVariables("REMOTE_ADDR") & "", "" strSql = StrSql & ChkString(Request.Form("Message")) & "", "" strSql = StrSql & ChkString(Request.Form("Rating")) & "")" objConn.Execute (StrSql) %>

После этого извлекаются и применяются параметры цветов, размеров, шрифтов оформления из соответствующей таблицы:

" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("FormTitleSize")%>">Спасибо за вашу запись в нашей гостевой книге!

" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>">Для просмотра вашей записи кликните здесь

А теперь отправьте электронное письмо менеджеру или администратору с уведомлением о поступлении нового сообщения в гостевую книгу в случае необходимости:

<% If Not(Request.Form("email"))="" AND objRec2("AutoEmail")=True then Name = Request.Form("name") Email = Request.Form("email") sFrom = objRec2("YourEmail") sTo=Email sSubject = "Спасибо, Ваша запись в нашей гостевой книге принята!" sMessage = "Дорогой(ая) " & Name & vbcrlf _ & vbcrlf _ & objRec2("ThankMessage") & vbcrlf _ & vbcrlf _ & vbcrlf Set objNewMail = CreateObject("CDONTS.NewMail") objNewMail.Send sFrom, sTo, sSubject, sMessage Set objNewMail = Nothing End If If objRec2("YouEmail")=True then Name = Request.Form("name") Home_Page = Request.Form("url") Email = Request.Form("email") Message = Request.Form("message") Country = Request.Form("Country") Address = Request.ServerVariables("REMOTE_ADDR") Rating = Request.Form("Rating") If Rating ="0" then Rating="No Rating" End If sFrom = objRec2("YourEmail") sTo= objRec2("YourEmail") sSubject = "Новое сообщение" sMessage = "Привет," & vbcrlf _ & "Новое сообщение поступило в гостевую книгу" & vbcrlf _ & vbcrlf _ & ":" & vbcrlf _ & vbcrlf _ & Message & vbcrlf _ & vbcrlf _ & "Детали сообщения:" & vbcrlf _ & "Ваше имя: " & Name & vbcrlf _ & "Email: " & Email & vbcrlf _ & "URL: " & Home_Page & vbcrlf _ & "Страна: " & Country & vbcrlf _ & "Рейтинг: " & Rating & vbcrlf _ & "Адрес: " & Address Set objNewMail = CreateObject("CDONTS.NewMail") objNewMail.Send sFrom, sTo, sSubject, sMessage Set objNewMail = Nothing End If End Sub %>

Форма ввода новых значений

Целесообразно также вовлечь в процедуру показ формы, служащей для добавления новых сообщений (обратите внимание, что форма замкнута на себе, то есть в качестве реакции на нее служит модуль, который именно ее и содержит):

<% Sub ShowForm(Sign) %>

>
"color=" <%=objRec2("PageFontColor")%>" size="<%=objRec2("FormTitleSize")%>"> Оставьте запись в нашей гостевой книге

">* Обозначает поля, которые обязательно нужно запомнить

colspan=2> " color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> Ваше имя: *
" size=30> <% If dictFields(LCase("name")) Then Response.Write " You must enter a name
" Else Response.Write "
" End If %>
colspan=2> " color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> Email:
" size=30>
colspan=2> " color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> URL:
" color=" <%=objRec2("PageFontColor")%> " size="<%=objRec2("PageFontSize")%>"> http:// " size=30>
colspan=2> " color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> Страна:
" size=30>
" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> Как Вы оцениваете наш сайт?
" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%> ">Ваши комментарии:*
" color="red" size="-2"> <% If dictFields(LCase("message")) Then Response.Write "Вы не ввели сообщение
" Else Response.Write "
" End If %>
<% End Sub %>

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

<% Sub Show NumPerPage=INT(objRec2("NumPerPage")) If Request.QueryString("page") = "" Then iPageCurrent = 1 Else iPageCurrent = CInt(Request.QueryString("page")) End If Set objRec = Server.CreateObject ("ADODB.Recordset") StrSql = "SELECT * FROM Messages ORDER BY ID DESC;" objRec.PageSize = NumPerPage objRec.CacheSize = NumPerPage objRec.Open StrSql,objConn,3,1,&H0001 iPages = objRec.PageCount TotalRows = objRec.RecordCount If iPageCurrent > iPages Then iPageCurrent = iPages If iPageCurrent < 1 Then iPageCurrent = 1 If iPages = 0 Then Response.Write "Не найденно записей!" Else ObjRec.AbsolutePage = iPageCurrent %>

" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> Всего в книге <%=TotalRows%> записей на <%=iPages%> странице(ах)

<% iRecordsShown = 0 Do While iRecordsShown < NumPerPage And Not objRec.EOF Rating = ObjRec("Rating") If IsNull(Rating) or Rating="0" then Rating = "nr" Else Rating = ObjRec("Rating") End If If IsNull(ObjRec("URL")) then Link = "Не указан URL" Else Link = "http://" & ObjRec("URL") & "" End If Email = FormatStr(ObjRec("Email")) Name = FormatStr(ObjRec("Name")) %>
"> " color="<%=objRec2("InfoFontColor")%>" size="<%=objRec2("InfoFontSize")%>"><%=ObjRec("DateID") %> "> " color="<%=objRec2("InfoFontColor")%>" size="<%=objRec2("InfoFontSize")%>">Оценка сайта: .gif" height="14" width="65">
"> " color="<%=objRec2("MessageFontColor")%>" size="<%=objRec2("MessageFontSize")%>"><%=FormatStr(ObjRec("Message"))%>
"> " color="<%=objRec2("InfoFontColor")%>" size="<%=objRec2("InfoFontSize")%>"> <% If IsEmpty(Email) or Email=" " then Response.Write Name Else Response.Write " " & Name End If %> "> " color="<%=objRec2("InfoFontColor")%>" size="<%=objRec2("InfoFontSize")%>"><%=FormatStr(ObjRec("Country")) %> IP:<%= ObjRec("IP") %> "> " color="<%=objRec2("InfoFontColor")%>" size="<%=objRec2("InfoFontSize")%>"> <%=Link%>

<% iRecordsShown = iRecordsShown + 1 objRec.MoveNext Loop if iPages > 1 then %>

" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>"> Pages: <% For I = 1 To iPages If I = iPageCurrent Then Response.Write "" & I & " " Else Response.Write "" & I & " " End If Next Response.Write "" Else Response.Write " " End If End If objRec.Close Set objRec = Nothing End Sub %>

Обратите внимание на то, каким образом формируется и осуществляется ссылка на просмотр следующей странички с такой «порцией» сообщений:

Response.Write "" & I & " "

Как видите, в качестве значения параметра page ей передается номер странички и впоследствии, если это значение не равно 1, показ сообщений начинается не с первого сообщения, а с того, которое окажется первым по счету на страничке с соответствующим номером, заданным в параметре:

<% NumPerPage=INT(objRec2("NumPerPage")) If Request.QueryString("page") = "" Then iPageCurrent = 1 Else iPageCurrent = CInt(Request.QueryString("page")) End If %> Далее следует исходный текст самого модуля, в котором осуществляются подключение к базе данных и извлечение записей (в описываемом примере это будет единственной записью) из таблицы административных настроек Admin: <% Set objConn = Server.CreateObject ("ADODB.Connection") objConn.Open StrConn Set objRec2 = Server.CreateObject ("ADODB.Recordset") ConfigSql = "SELECT * FROM Admin;" objRec2.Open ConfigSql,objConn,0,1,&H0001 %>

Затем можно оформить заголовок и основные тэги HTML-странички:

ASP на блюдечке часть 15 - Гостевая книга своими руками

" color="<%=objRec2("PageFontColor")%>" size="<%=objRec2("PageFontSize")%>">

Просмотреть гостевую книгу | Оставить запись в гостевой книге

И наконец, главный цикл обработки вашей главной и единственной asp-странички модуля будет выглядеть следующим образом:

<% select case Request.QueryString("mode") case "post" Dim Field Dim dictFields Set dictFields = Server.CreateObject("Scripting.Dictionary") For Each Field in Request.Form If ValidateField(Request.Form(Field), Field) = False Then dictFields.Add LCase(Field), True End If Next If Request.Form.Count <> 0 And dictFields.Count = 0 Then Call Update Else If Request.Form.Count <> 0 Then End If ShowForm("Sign") End If case "show" Call Show case Else Call Show End Select %>

Здесь рассматриваются всего два случая (case), соответствующие двум функциям нашего Web-приложения: добавлениe новой записи в гостевую книгу (значение параметра mode = “post”) и просмотр сообщений гостевой книги (значение параметра mode = “show”).

<% objRec2.Close Set objRec2 = Nothing s objConn.Close Set objConn = Nothing Response.Write "

" %>

Заключение

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

Следовало бы, конечно, рассмотреть и Web-интерфейс для редактирования, добавления и удаления административных настроек (схем), однако это займет много времени, и поэтому автор постарается освeтить его в одной из следующих частей настоящей статьи.

КомпьютерПресс 11"2001

Регистрация элементов управления осуществляется директивой @Register, которая позволяет использовать в HTML коде страницы user controls и server controls, используя специальный синтаксис (declarative custom server control syntax). Парсер страниц на основе анализа этих директив может связывать теги с заданными типами и при создании страницы встраивать элементы управления уже как контейнеры пользовательских типов – ветви дерева элементов управления страницы.

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

В статье описан способ, упрощающий регистрацию элементов управления.

Для директив регистрации мы будем использовать обычный текстовый файл, в котором соберем все директивы @ Register. Так как для объявления user controls можно использовать виртуальные пути, а для server controls указываются лишь пространства имен, мы можем собрать в этом файле все нужные нам ссылки, причем ссылки на файлы ascx будут верными для любой папки проекта. Вот как выглядит этот файл в одном из проектов:


<%@ Register TagPrefix="ch" Namespace="ControlsSharp.HtmlControls" Assembly="ControlsSharp"%>

<%@ Register TagPrefix="cw" Namespace="ControlsSharp.WebControls" Assembly="ControlsSharp"%>

<%@ Register TagPrefix="c" Namespace="ControlsSharp.CustomControls" Assembly="ControlsSharp"%>

<%@ Register TagPrefix="b" Namespace="ControlsBasic.CustomControls" Assembly="ControlsBasic"%>

<%@ Register TagPrefix="cu" TagName="bottommenu" Src="~/UserControls/Menu/cu_menu_bottom.ascx" %>

<%@ Register TagPrefix="cu" TagName="leftmenu" Src="~/UserControls/Menu/cu_menu_left.ascx" %>

<%@ Register TagPrefix="cu" TagName="topmenu" Src="~/UserControls/Menu/cu_menu_top.ascx" %>

Назовем файл register.inc и поместим в папку /inc нашего веб-проекта.

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

Теперь созданный файл нужно каким-то образом включить в код страницы. Мы сделаем это с помощью директивы SSI (server side includes) #include. Эта директива позволяет включать в код страницы статические и динамические файлы, обрабатывая их на основе маппинга IIS, т.е. указание в качестве источника файла asp или aspx приведет к обработке файла соответствующим процессом и копированию результатов этой обработки в выдаваемую страницу. В ASP директива #include очень широко использовалась и позволяла реализовать модульность сайта. С появлением ASP.NET это стало удобнее делать другими способами, например, с помощью user controls. В следующих версиях ASP.NET модульность будет реализована с использованием master pages. В общем, директива #include потеряла свое значение и была сохранена в основном для обратной совместимостью и для упрощенной миграции ASP проектов на.Net.

Так как у нас простой текстовый файл, никакой обработки произведено не будет, и до выполнения любого динамического контента все содержимое файла будет скопировано в код страницы. Т.е. добавление нашего файла register.inc, например, в начало страницы, это почти то же самое как будто бы мы напишем там все директивы @ Register.

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

Убедитесь, что все работает, если нет, поправьте неверно указанные пути.

Осталось осуществить еще одну операцию. Сейчас, если вы попробуете по ссылке в браузере получить файл /inc/register.inc, вы без труда сможете это сделать. IIS отдает его в ваши руки, так же как в руки злоумышленника, совершенно свободно, хотя там содержатся пути физической структуры вашего сайта.

Для того чтобы этого не происходило, мы используем возможности синхронного обработчика HttpForbiddenHandler, позволяющего защищать файлы определенного типа от выдачи по запросам пользователя. Этот подход удобен и часто используется, например, для защиты файлов баз данных MS Access, используемых в проекте. Для того чтобы файлы с расширение *.inc можно было защитить с помощью этого обработчика нужно сообщить IIS что эти файлы будет обрабатывать процесс ASP.NET, другими словами настроить в IIS маппинг на файлы этого типа.

Подробное описание процесса настройки для IIS описано в статье HOW TO: Use ASP.NET to Protect File Types (http://support.microsoft.com/kb/815152/EN-US/). Нам потребуется создать маппинг только для файлов типа *.inc. После выполнения описанных там шагов, все запросы к файлам с таким расширением будут обрабатываться процессом ASP.NET, и вам останется отредактировать файл web.config следующим образом:

Все, теперь при попытке получить файл /inc/register.inc по прямой ссылке пользователь получит ошибку В.

Чтобы не регистрировать aspnet_isapi.dll, например, ваш провайдер не хочет этого делать можно воспользоваться возможностью SSI указывать файлы любого типа и схитрить, использовав для файла с директивами @Register расширение одного из типов, уже маппированных в IIS по умолчанию. Для этого будут удобны расширения *.cs или *.vb. Эти файлы содержат исходный код и обычно не копируются на сервер. Если вы вдруг ошиблись и скопировали, по запросу из браузера их получить не удастся, - при попытке это сделать пользователь получит ошибку В. Так происходит потому, что для фалов этого типа маппинг в IIS настроен по умолчанию а соответствующее расширение уже прописано в секции файла machine.config. В Visual Studio для того чтобы компилятор не выдавал вам сообщение об ошибке, поставьте расширение которое компилятор не интересует: в проектах на C# это *.vb, в проектах VB - *.cs.
Заключение

Описанный способ позволяет регистрировать элементы управления в одном месте для всего проекта. Последующая модификация этого файла требует меньше усилий по сравнению с тем, как если бы пришлось делать это обычным способом. Попробуйте использовать SSI #include внутри самих вставляемых файлов – это позволяет организовать подобие иерархии и наследования, что может быть удобно для крупных проектов

Directives in AngularJS play an important role. Directives can be used to teach new tricks to HTML, and you can even create your own HTML tags or attributes. Directives also help in keeping the mark-up more fluent and defines a nice way of separating code and mark-up from each other.

View is a HTML template. View is nothing but the information you want to render to the end user’s browser. A view in AngularJS is also called as compiled DOM . View makes use of directives to render the data with HTML template.

This article is Part IV of the Project Tracking Website built in AngularJS and ASP.NET Web API. So far, we have , created a , and have .

Thanks to to review this Angular series and fix the bugs.

We have already seen the $scope object which provides a Model to the View. Model code is not intermixed with the HTML code we write into our views. Rather data is moved from the model to views by using data binding expressions. This way developers can achieve Separation of Concerns (SoC). Since Models are independent of Views, they can be bound to any View. This binding of model is done with the help of AngularJS Directives.

We have already seen some Angular directives in our like ng-app which bootstraps AngularJS, as well as ng-controller that makes the controller available to HTML. From the controller, we can bind the data to the views using Angular {{expression}}.

In this article, we will look at a couple of additional AngularJS directives which come out-of-the-box with Angular. One of them is ng-repeat . Let’s try using ng-repeat directive into our EmployeeDetails.html page that can be found in the accompanying this article. Modify the service URL in our EmployeesController.js file. The service URL is as follows:

http://localhost:2464/api/ptemployees

Now we will modify the EmployeeDetails.html page as shown in following code -

{{emp.employeeID}} {{emp.employeeName}} {{emp.designation}} {{emp.contactNo}} {{emp.eMailID}} {{emp.skillSets}}

Replace the of EmployeeDetails.html page with above code. The output of the above code is shown here:

In this code, we have used the ng-repeat directive of AngularJS. It is similar to the for or foreach loop in .NET. Here we are getting an IEnumerable collection using ASP.NET Web API. We are using this collection as a model in our Angular Controller. Using this model, we are iterating the objects of employees, into our view. This is a very helpful directive which repeats through the objects in the collection to display the data on the view.

Now let’s try adding a filter to search a particular Employee from the collection and display the employee based on given Employee Name or Employee Name character. Till now, we have fetched the model and used it in our Views. It also works the other way. We can make our views talk back to our models which are there in our controllers.

To add a search filter based on Employee Name, we will modify the EmployeeDetails.html page by adding HTML input elements as shown below -

Enter Employee Name Or Character To Search -

Add the above code just after the

tag. In the above code, we are using ng-model directive which enables us to send the data back to the model. Based on this data, we will make a search for an employee using EmployeeName property. Make sure that EmployeeName property is declared in our model, which we will do in the following steps. Also notice that we are using ng-submit directive which will give a call to SearchEmployee function from our controller.

Now let’s modify the EmployeesController.js file so that we can search the employee based on EmployeeName property as a searching criteria. The code is shown below -

(function () { var EmployeesController = function ($scope,$http) { var employees = function (serviceResp) { $scope.Employees = serviceResp.data; }; $scope.SearchEmployees = function (EmployeeName) { $http.get("http://localhost:2464/api/ptemployees/" + EmployeeName) .then(employees, errorDetails); }; var errorDetails = function (serviceResp) { $scope.Error="Something went wrong ??"; }; $http.get("http://localhost:2464/api/ptemployees") .then(employees,errorDetails); $scope.Title = "Employee Details Page"; $scope.EmployeeName = null; }; app.controller("EmployeesController", EmployeesController); }());

In the above code, we have added the SearchEmployee() method to our $scope object as a model. This method will search for Employees based on employee name or the character of an employee name. We have also declared EmployeeName property in our controller at the end of this code. The SearchEmployees method fetches the Web API method. I have modified the method GET as shown here:

Public HttpResponseMessage Get(string name) { var employees = EmployeesRepository.SearchEmployeesByName(name); HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, employees); return response; }

The Employee Repository code is as shown here:

Public static List SearchEmployeesByName(string employeeName) { ProjectTrackingDBEntities dataContext = new ProjectTrackingDBEntities(); var query = from employee in dataContext.Employees where employee.EmployeeName.Contains(employeeName) select employee; return query.ToList(); }

After all these changes, now run the EmployeeDetails.html page and see the output.

In the above output, we are searching for employees whose name contains the ‘J’ character in it.

AngularJS Filters extend the behavior of binding expressions or directives. Filters are used with binding expressions to format the data being bound. When they are used with directives, they add some additional actions to the directives. Out-of-the-box, AngularJS provides a number of filters which we can use to format the values of an expression and display the values/data into our views. You can make use of filters in Views, Controllers and Services. The syntax of using filters into views is {{ expression | filter1 | filter2 | ...}}.

We will now try a filter which will sort the data using employee name. To sort the data, let’s add a filter in our ng-repeat using a | operator as shown here:

In the above code, we are adding filter in our ng-repeat directive. The orderBy:’employeeName’ will sort the data using Employee name in an ascending order. You can observe the output here:

To display the data in descending order, you can change the filter as shown here:

In the above code, to sort the employee names in descending order, we have used (-) minus sign. Likewise, you can make use of (+) sign to sort it in ascending.

You can also make use limitTo filter to limit the number of records. For example, let us say at a time you want to display 5 employees. To display the restricted number of records in our EmployeeDetails.html page, let’s modify the ng-repeat directive as shown here-

The output is shown here:

Now if you run the ProjectDetails.html page, the date is getting displayed with time. You can apply the date filter as shown in following code -

{{proj.projectID}} {{proj.projectName}} {{proj.startDate|date:"short"}} {{proj.endDate|date:"short"}} {{proj.clientName}}

The output of this page is as follows:

You can make use of different date formats like - fulldate, longdate, mediumdate, shortdate etc. Now let’s open EmployeeDetails.html page and run it. I am using the ‘Z’ character to display employees whose employee name contains Z.

If you observe, the output displays an Employee table heading without data. We can make the heading invisible using the ng-show directive when the filter doesn’t produce any result. Apply ng-show directive in our table tag as shown in the below code and try running the application with Z character. Now you will not see the table columns when Employees model is null. The ng-show attribute will evaluate the Employees model and accordingly it will either display the table or hide the table.

Likewise, there are a number of directives which you can use in AngularJS. You can also design a Custom Directive which we will see later in this series. Apply the search on various views as per your requirement in our views. In our next article, we will take a look at