Search for words using additional operators. Creating and preparing a database

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.

What is a guestbook?

Of course, here we are talking about the most typical guest book. First of all, this is a system that provides the user with the ability to enter text, select an assessment of a particular site, and also to specify their own data (name, e-mail, http, etc.). It is also a system for presenting data entered by various users, with the ability to navigate, send emails to the authors of the messages. Variations are also possible with different settings and with the control of normative vocabulary.

What do we need

Of course, it is assumed that the reader is familiar with the basics of ASP and SQL programming (familiarity with the first parts of this article will be quite enough for this). In addition, we need Microsoft SQL Server 7.0 or 2000, some HTML or text editor (I recommend using Macromedia Dreamweaver UltraDev 4.0) and a little patience.

Creating and preparing a database

To organize the storage of data entered by users, you need one table where you can create fields for storing the user's name, his email address, country of residence, site address, IP address, site user rating value on a five-point scale, etc.:

In order to easily integrate the system into existing sites, it is recommended to plan another table for storing color and other settings. This will allow you to change the specified settings in the future without changing the corresponding parameters in the source texts of the guestbook application modules.

  • Run the Data Sources ODBC Configurator - Start->Settings->Control Panel->Administrative Tools->Data Sources ODBC.
  • Go to the System DSN tab and create a new data source by clicking on Add…
  • In the list of drivers that appears, select the database driver - Microsoft SQL Server and click Next.
  • In the Data Source Name line, specify the name of your database (in the described example, Gustbook is the name by which you will refer to it in the future).
  • In the Server line, specify the server to which the connection will be made, and click Next.
  • Select the authentication mode With SQL Server…, set the username and password to connect to the SQL server; define the protocol for communication with the server (button Client Configuration - TCP/IP) and click Next twice, then click Finish.
  • You will see statistics about the actions taken, and you can use the Test Data Source button to check the data source.
  • As a result, you will see a line in the list of data sources in your system.

Now that the database is ready, you can proceed directly to creating a guest book.

Integration of the system into a ready-made website

It is clear that the guestbook itself does not make sense. Judge for yourself: who needs a site designed solely to collect the opinions of readers. After all, in order to collect opinions about something, you must first present this something to their judgment. Therefore, it is necessary to pay special attention to the issues related to the simplification of embedding the system into ready-made sites.

In particular, to make it easier to customize the system for the characteristic features of a particular site, it is recommended (as mentioned above) to create a special table to store all these preferences in order to enter certain values ​​specific to your site into it. The obvious advantage of this approach is that in order to embed the system into an already finished site, you do not need to make changes in the source code of the modules, you only need to change the settings in the corresponding database table.

Imagine an example of the implementation of such a table: .

As you can see, there are fields for storing information about the name and password for accessing the system setup mode, about the colors of the main background of the user's message, the top and bottom frames (Mid_Color, Top_Color, Bot_Color fields, respectively), about the color and size of the header of the form used for entering user data (Form_Color and FormTitleSize fields, respectively), about the color, size and style of the font of the text of the message itself, information fields, as well as the guestbook pages themselves (fields MessageFontColor, MessageFontSize, MessageFontFace, InfoFontColor, InfoFontSize, InfoFontFace, PageFontColor, PageFontSize and PageFontFace respectively), switch fields to enable the automatic sending of notifications of new messages by e-mail to the responsible person (for example, the manager or site administrator), fields for storing the e-mail address of the responsible person, the text of the message with thanks for the message left by the user, with the list are not allowed x words and a switch for their filtering mode (if the latter is enabled, then the words in the list of invalid words will be automatically replaced in the message text with asterisks and thus control over the normativeness of the vocabulary of the site texts will be exercised).

The development of the guest book integration system implies the organization of a Web interface for setting all the parameters we have considered (fields of the administration table).

Integration of the system into an already finished site in its pure form can create some difficulties both in the perception of the source text and in the future, if, for example, you need to temporarily disable the guest book on a particular site. Therefore, we will try to develop the system in such a way that its integration into the finished site is not difficult. To do this, it is necessary to form an independent module of the system and include it in the text of the main site where necessary. So, for example, the text of your website page might look like this:

ASP on a silver platter (Part - 15) – Guest book

As you can see, in the first case, the directive to include a page with a guest book () is indicated in the right place, and in the second case, the page of the original site is presented simply in the form of three sequentially included elements: the beginning, the guestbook page, and the end. Using this or that way of organizing the page structure of your site is a matter of taste and depends both on the structure of the original site and on the degree of its complexity.

Guestbook main page (Guest.asp file)

The presented application will have only one page, which will serve both for displaying user messages, and for navigating and entering new messages. Depending on the values ​​of the key parameters, one or another action will be performed, and the page will be in one state or another. First of all, you will need to develop that part of it, which will display user messages and which will contain links to the part that serves to add new messages.

First, let's write a few functions for working with strings:

  1. The function to replace an empty string with a space and a single quote with a double one:<% Function ChkString(string) If string = "" then string = " " ChkString = Replace(string, """, """") End Function %>
  2. The function of checking the vocabulary of the message text for normativity. If words match words from the list of invalid words, replace them with asterisks:<% 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. The function of formatting the text entered by the user. If necessary (if there is a corresponding flag in the database), the text will be checked (filtered) for normativity:<% 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. Field check function:<% 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. The procedure for adding new messages (pay attention to how the IP address of the computer from which the message was sent is calculated):
<% 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) %>

After that, the parameters of colors, sizes, design fonts are extracted and applied from the corresponding table:

"color="<%=objRec2("PageFontColor")%>"size="<%=objRec2("FormTitleSize")%>">Thank you for your entry in our guestbook!

"color="<%=objRec2("PageFontColor")%>"size="<%=objRec2("PageFontSize")%>"> Click here to view your entry

Now, send an email to the manager or administrator notifying you of a new guestbook entry, if necessary:

<% 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 %>

Form for entering new values

It is also advisable to involve in the procedure the display of a form used to add new messages (note that the form is closed on itself, that is, the module that contains it serves as a reaction to it):

<% Sub ShowForm(Sign) %>

>
"color="<%=objRec2("PageFontColor")%>"size="<%=objRec2("FormTitleSize")%>"> Leave an entry in our guest book

">* Indicates fields that must be remembered

colspan=2> "color="<%=objRec2("PageFontColor")%>"size="<%=objRec2("PageFontSize")%>"> Your name: *
"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")%>"> The country:
"size=30>
"color="<%=objRec2("PageFontColor")%>"size="<%=objRec2("PageFontSize")%>"> How do you rate our website?
"color="<%=objRec2("PageFontColor")%>"size="<%=objRec2("PageFontSize")%> ">Your comments: *
"color="red" size="-2"><% If dictFields(LCase("message")) Then Response.Write "Вы не ввели сообщение
" Else Response.Write "
" End If %>
<% End Sub %>

This is followed by the main function to display a fixed number of user messages (the value retrieved from the administrative settings table):

<% 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")%>"> Total in the book <%=TotalRows%> entries on <%=iPages%> page(s)

<% 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")%>">Site rating: .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 %>

Pay attention to how the link to view the next page with such a “portion” of messages is formed and implemented:

Response.Write" "&I&" "

As you can see, the page number is passed to it as the value of the page parameter, and subsequently, if this value is not equal to 1, the display of messages does not start from the first message, but from the one that will be the first in the account on the page with the corresponding number specified in the parameter:

<% NumPerPage=INT(objRec2("NumPerPage")) If Request.QueryString("page") = "" Then iPageCurrent = 1 Else iPageCurrent = CInt(Request.QueryString("page")) End If %>The source text of the module itself follows, in which the connection to the database is made and records are retrieved (in the described example, this will be the only record) from the Admin administrative settings table:<% 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 %>

Then you can style the title and main tags of the HTML page:

ASP on a silver platter part 15 - DIY guest book

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

View guest book | Leave an entry in the guestbook

And finally, the main loop for processing your main and only asp page of the module will look like this:

<% 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 %>

Only two cases are considered here, corresponding to two functions of our Web application: adding a new entry to the guestbook (the value of the mode parameter = “post”) and viewing guestbook messages (the value of the parameter mode = “show”).

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

" %>

Conclusion

We considered one more functional component of the site, and immediately made it portable. The result of this was a rather complex source code in terms of perception. Although a large number of parameters retrieved from the administrative table made it somewhat more difficult to understand the source code of the module, however, using them once and for all will save you from having to edit the code when they change. The system developed by us is quite acceptable in use, and thanks to the modularity of its implementation and the approach to its implementation in existing sites described in the article, it can be used as a guest book on a site of almost any degree of complexity.

Of course, the Web interface for editing, adding and deleting administrative settings (schemes) should also be considered, but this will take a lot of time, and therefore the author will try to cover it in one of the following parts of this article.

ComputerPress 11 "2001

Registration of controls is carried out by the @Register directive, which allows you to use user controls and server controls in the HTML code of the page using a special syntax (declarative custom server control syntax). Based on the analysis of these directives, the page parser can associate tags with given types and, when creating a page, embed controls already as containers of custom types - branches of the page's control tree.

Directives must precede the first use of the declared tags, more often they are placed at the beginning of the page and in the case of registering several controls, in sites with a modular structure, the number of such declarations can occupy a large number of lines. When you change the location of controls, you have to look for lines that require changes in the code of all pages and user controls on which they are registered, which is rather inconvenient.

The article describes a method that simplifies the registration of controls.

For the registration directives, we will use a plain text file in which we will collect all the @ Register directives. Since virtual paths can be used to declare user controls, and only namespaces are specified for server controls, we can collect all the links we need in this file, and the links to the ascx files will be correct for any folder in the project. Here is what this file looks like in one of the projects:


<%@ 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" %>

Let's name the file register.inc and place it in the /inc folder of our web project.

This file will contain all the links we need, we will add or change the registration of a user or server control in it.

Now the created file needs to be somehow included in the page code. We do this with the SSI (server side includes) #include directive. This directive allows you to include static and dynamic files in the page code, processing them based on IIS mapping, i.e. specifying an asp or aspx file as the source will cause the file to be processed by the appropriate process and copy the results of this processing to the output page. In ASP, the #include directive was very widely used and allowed for the modularization of the site. With the advent of ASP.NET, it has become more convenient to do this in other ways, for example, using user controls. Future versions of ASP.NET will implement modularity using master pages. In general, the #include directive lost its meaning and was kept mainly for backward compatibility and to simplify the migration of ASP projects to .Net.

Since we have a simple text file, no processing will be done, and before any dynamic content is executed, the entire contents of the file will be copied into the page code. Those. adding our register.inc file to the top of the page, for example, is almost the same as writing all the @Register directives there.

In order not to depend on the physical location of the file, we again use the virtual path syntax and add the following line to the aspx file code:

Make sure everything works, if not, correct the wrong paths.

It remains to carry out one more operation. Now, if you try to get the /inc/register.inc file from the link in your browser, you can easily do it. IIS puts it in your hands, as well as in the hands of an attacker, completely free, although it contains the paths of the physical structure of your site.

To prevent this from happening, we use the capabilities of the synchronous HttpForbiddenHandler handler, which allows us to protect files of a certain type from being issued at the request of the user. This approach is convenient and is often used, for example, to protect MS Access database files used in a project. In order for files with the *.inc extension to be protected using this handler, you need to tell IIS that these files will be processed by the ASP.NET process, in other words, configure IIS to map to files of this type.

For a detailed description of the configuration process for IIS, see HOW TO: Use ASP.NET to Protect File Types (http://support.microsoft.com/kb/815152/EN-US/). We need to create a mapping only for *.inc files. After completing the steps described there, all requests for files with this extension will be processed by the ASP.NET process, and you will have to edit the web.config file as follows:

That's it, now when trying to get the /inc/register.inc file via a direct link, the user will receive error B.

In order not to register aspnet_isapi.dll, for example, your provider does not want to do this, you can use the SSI ability to specify files of any type and cheat by using an extension of one of the types already mapped in IIS by default for a file with @Register directives. *.cs or *.vb extensions will be convenient for this. These files contain source code and are usually not copied to the server. If you suddenly made a mistake and copied, you won’t be able to get them at the request from the browser - when you try to do this, the user will receive an error B. This happens because mapping in IIS is configured by default for files of this type and the corresponding extension is already registered in the section machine.config file. In Visual Studio, in order for the compiler not to give you an error message, put an extension that the compiler is not interested in: in C# projects it is *.vb, in VB projects it is *.cs.
Conclusion

The described method allows you to register controls in one place for the entire project. Subsequent modification of this file requires less effort than if you had to do it in the usual way. Try using SSI #include inside the files you insert - this allows you to organize a kind of hierarchy and inheritance, which can be convenient for large projects

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 an 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 the 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 the 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 = "(!LANG: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 GET method 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 the 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