We seem to be getting more and more email's from customers looking to work with the InstantKB.NET API from within there own ASP.NET web sites To address these questions i've created this article which shows how to bind a collection of InstantKB.NET articles to a standard ASP.NET gridview. This example provides paging & basic sorting features.
Whilst this is quite a simple example it does demonstrates some important aspects to consider when using our API from your own web application. The InstantKB.NET API allows you to programatically control every aspect of your InstantKB.NET data through code. Our assemblies can be referenced from any .NET project (C# or VB.NET) to take advantqage of our methods.
The Scenario
One common scenario we see are customers looking to display articles on there own web sites. While you can already display articles via our RSS feeds this does incur some network overhead. Taking advantage of our API to query & display articles offers greater flexibility & much better performance.
Whilst this is only a simple use of our API it does demonstrate how you would reference our assemblies from within your Visual Studio.NET projects.
Once we have the basics working we'll add some simple search options to demonstrate how to can query the InstantKB.NET articles via our API to return results matching specific search criteria. For example on your web site you may wish to display all articles with a high priority or specific status.
We'll also take things a step further and demonstrate how to programatically add articles using our API through a simple web form.
Lets get started
If you wish to follow the steps within this article you will need a copy of Visual Studio.NET 2005 or 2008. To help with our scenario we'll create a basic ASP.NET Web Site to serve as a test bed to implement our code. The source code for this example can be found at the bottom of this page.
1. We'll quickly create a web site we can use to test our code.

Select a standard ASP.NET web site...

Once created you'll be presented with a blank web site as shown below...

To take advantage of our API you will need to reference our assemblies from your Visual Studio.NET solution. To add a reference to our assemblies simply right click on your project and go to "Add Reference" as shown below...

You will need to browse to the InstantKB.NET installation folder and locate the "InstantASP.InstantKB.UI.dll" file within the "\bin" directory...

Adding this single assembly as a reference to your project will bring all other dependencies into your solution as shown below...

Great. Now you've added references you'll just need to add a few settings to your root web site web.config file.
You will need to modify your web sites web.config file to include the InstantKB.NET database connection string and virtual path...

Application settings
In order for our assemblies to know which database to communicate with & which directly to search within for the Pages.config & URLRewrite.config file you will need to add the following application settings to your web.config file...
<appSettings>
<add key="InstantASP_ConnectionString"
value="Server=localhost;trusted_connection=true;database=InstantKB205;"/>
<add key="InstantASP_VirtualPath" value="/InstantKB20"/>
</appSettings>
Forms Authentication
In order to take advantage of our built in role based security when querqueryingp; displaying articles you will need to add the following to your web.config file...
<authentication mode="Forms">
<forms name="InstantASP" loginUrl="Logon.aspx"
protection="All" slidingExpiration="true" path="/"/>
</authentication>
You will need to add the following HTTP Module...
<httpModules>
<!-- required to populate System.Web.HttpContext.Current.User -->
<add type="InstantASP.Common.HttpModule.SecurityModule,
InstantASP.Common" name="SecurityModule"/>
</httpModules>
Certain methods within our API require access to the configuration files provided with InstantKB.NET. For example if you wish to use our API to build up a dynamic URL to an article you will need to call methods within our API that depend on our Pages.config file. This file is a simple XML file that defines all the file names used within InstantKB.NET. This allows you to easily change the name of files to better suite your requirements.
Because of this however when using our API from outside of InstantKB.NET you will need to let our assemblies know where to find the various configuration Files such as Pages.config, URLRewrite.config. Todthis imply add a copy of InstantKB.NET to your web site and ensure the InstantASP_VirtualPath setting within your root web.config is present and using the correct virtual path to your InstantKB.NET folder.
If you don't want to install full copy of InstantKB.NET under your web site you can simply copy the Pages.config and URLRewrite.config files into the root of your InstantKB20 folder. Add the InstantKB20 folder (you can rename this) to your web site...

Ensure the following Application setting is present in your root web.config file...
<appSettings>
<add key="InstantASP_VirtualPath" value="/InstantKB20"/>
</appSettings>
The value for this setting much match the name of your InstantKB.NET folder.
Now you've added the asseassemblyerences and necessary web.config settings you can start using the methods within our API from your own web site. In this example we'll be showing how to bind articles to a grdiview and provide basic options to query the results.
Lets add a gridview to our ASP.NET web form. Double-check the defualt.aspx file and select the "Design" Mode as shown below...

Open your control toolbox on the left of the design surface and locate the GridView control...

Drag the GridView control into the designer. This should create a basic control as shown below...

6. Wire-up the GridView to show InstantKB.NET Articles
Now we have a GridView control to work with the next step is to add some code within the Page_Load event to bind our articles to the GridView. You can do this with some simply code such as...
Partial Class _Default
Inherits System.Web.UI.Page
#Region "Private VAraiables"
Private m_User As InstantASP.InstantKB.Components.User
Private m_SearchEventArgs As InstantASP.InstantKB.Components.SearchEventArgs
#End Region
#Region "Public Properties"
Public Property SearchEventArgs() As InstantASP.InstantKB.Components.SearchEventArgs
Get
If m_SearchEventArgs Is Nothing Then
m_SearchEventArgs = New InstantASP.InstantKB.Components.SearchEventArgs
m_SearchEventArgs.UserID = CurrentUser.UserID
End If
Return m_SearchEventArgs
End Get
Set(ByVal value As InstantASP.InstantKB.Components.SearchEventArgs)
m_SearchEventArgs = value
End Set
End Property
Public ReadOnly Property CurrentUser() As InstantASP.InstantKB.Components.User
Get
If m_User Is Nothing Then
m_User = GetUser()
End If
Return m_User
End Get
End Property
#End Region
#Region "Page Events"
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
' bind data
BindData(GridView1.PageIndex, GridView1.PageSize, SearchEventArgs)
End If
MyBase.OnLoad(e)
End Sub
#End Region
#Region "Private Methods"
Private Sub BindData(ByVal intPageIndex As Int32, ByVal intPageSize As Int32, _
ByVal SearchEventArgs As InstantASP.InstantKB.Components.SearchEventArgs)
' setup gridview with current page index
GridView1.PageIndex = intPageIndex
GridView1.PageSize = intPageSize
' build SQL statements based on search event args object
Dim strPopulateSQL As String = _
InstantASP.InstantKB.Business.Search.SQLPopulate(SearchEventArgs)
Dim strCountSQL As String = _
InstantASP.InstantKB.Business.Search.SQLCount(SearchEventArgs)
Dim strFulltextSQL As String = _
InstantASP.InstantKB.Business.Search.SQLFullTextMaxRank(SearchEventArgs)
' return articles matching the search options & only within the page range
Dim ArticleCollection As InstantASP.InstantKB.Collections.ArticleCollection = _
InstantASP.InstantKB.Business.Articles.SelectArticlesPaged( _
intPageIndex, intPageSize, strPopulateSQL, strCountSQL, True, strFulltextSQL)
If Not ArticleCollection Is Nothing Then
GridView1.Visible = True
GridView1.DataSource = ArticleCollection
GridView1.DataBind()
Else
GridView1.Visible = False
End If
End Sub
' -------------------------------------
' helpers
' -------------------------------------
' get InstantKB.NET user object
Private Function GetUser() As InstantASP.InstantKB.Components.User
Dim User As InstantASP.InstantKB.Components.User = Nothing
If System.Web.HttpContext.Current.User.Identity.IsAuthenticated Then
User = InstantASP.InstantKB.Business.User.SelectUser( _
System.Web.HttpContext.Current.User.Identity.Name)
Else
User = New InstantASP.InstantKB.Components.AnonymousUser
End If
Return User
End Function
Private Function GetCulture() As String
If CurrentUser.Culture <> "" Then
Return CurrentUser.Culture
End If
Return InstantASP.Common.Application.Settings.Instance().Culture
End Function
#End Region
End Class
You'll notice we simply call our BindData method to obtain a collection of articles and bind these to our GridView. The SearchEventsArgs property allows you to filter results based on specific search criteria. You'll notice we populate the UserID property of the SearchEventArgs object when we initialize this object within the property. This UserID is required for role based security to work correctly and ensure only articles belonging to your member groups are displayed.
We have two basic private helper methods to return the current authenticated user & the current culture for the application.
After implementing this code, if you build your solution (CTRL+F5) you should see something like...

This indicates the InstantKB.NET article collection was returned and bound to your GridView control.
Lets extend this example and add some basic search functionality. This will demonstrate how the InstantASP.InstantKB.Componanent.SearchEventArgs object can be used to filter and display different results based on search input.
We'll add a basic keyword search & three drop down lists. The first drop down list will contain a list of tabs and allow us to filter results by tab. The second drop down list will contain a list of status' from within InstantKB.NET and allow us to search by status & the third will contain a list of priorities and will allow us to filter articles by priority.
To get start open your Default.aspx file again within Design View. Expand your control toolbox and drag a textbox, button & three drop down lists onto your page designer as shown below...

Now we have our controls we'll need to modify the code-behind for our Default.aspx page. Within the solution explorer locate the "Default.aspx.vb" file. Open this and modify as shown below...
Partial Class _Default
Inherits System.Web.UI.Page
#Region "Private VAraiables"
Private m_User As InstantASP.InstantKB.Components.User
Private m_SearchEventArgs As InstantASP.InstantKB.Components.SearchEventArgs
#End Region
#Region "Public Properties"
Public Property SearchEventArgs() As InstantASP.InstantKB.Components.SearchEventArgs
Get
If m_SearchEventArgs Is Nothing Then
m_SearchEventArgs = New InstantASP.InstantKB.Components.SearchEventArgs
m_SearchEventArgs.UserID = CurrentUser.UserID
End If
Return m_SearchEventArgs
End Get
Set(ByVal value As InstantASP.InstantKB.Components.SearchEventArgs)
m_SearchEventArgs = value
End Set
End Property
Public ReadOnly Property CurrentUser() As InstantASP.InstantKB.Components.User
Get
If m_User Is Nothing Then
m_User = GetUser()
End If
Return m_User
End Get
End Property
#End Region
#Region "Page Events"
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
' populate tab drop down list
PopulateTabsDropDown()
' populate status drop down list
PopulateStatusDropDown()
' populate priority drop down list
PopulatePriorityDropDown()
' bind data
BindData(GridView1.PageIndex, GridView1.PageSize, SearchEventArgs)
End If
MyBase.OnLoad(e)
End Sub
#End Region
#Region "Private Methods"
Private Sub BindData(ByVal intPageIndex As Int32, ByVal intPageSize As Int32, _
ByVal SearchEventArgs As InstantASP.InstantKB.Components.SearchEventArgs)
GridView1.PageIndex = intPageIndex
GridView1.PageSize = intPageSize
' build SQL statements based on search event args object
Dim strPopulateSQL As String = _
InstantASP.InstantKB.Business.Search.SQLPopulate(SearchEventArgs)
Dim strCountSQL As String = _
InstantASP.InstantKB.Business.Search.SQLCount(SearchEventArgs)
Dim strFulltextSQL As String = _
InstantASP.InstantKB.Business.Search.SQLFullTextMaxRank(SearchEventArgs)
' return articles matching the search options & only within the page range
Dim ArticleCollection As InstantASP.InstantKB.Collections.ArticleCollection = _
InstantASP.InstantKB.Business.Articles.SelectArticlesPaged( _
intPageIndex, intPageSize, strPopulateSQL, strCountSQL, True, strFulltextSQL)
If Not ArticleCollection Is Nothing Then
GridView1.Visible = True
GridView1.DataSource = ArticleCollection
GridView1.DataBind()
Else
GridView1.Visible = False
End If
End Sub
Private Sub PopulateTabsDropDown()
' get tab collection - pass userid for role based security
Dim TabCollection As InstantASP.InstantKB.Collections.TabCollection = _
InstantASP.InstantKB.Business.Tabs.SelectTabs(CurrentUser.UserID)
' ensure we have a tab collection
If Not TabCollection Is Nothing Then
' add empty item
DropDownList1.Items.Add("-")
' get current culture
Dim strCulture As String = GetCulture()
' enumerate through tabs
For intCount As Int32 = 0 To TabCollection.Count - 1
' get tab
Dim Tab As InstantASP.InstantKB.Components.Tab = TabCollection(intCount)
' get tab text
Dim strTabTExt As String = Tab.TabText(strCulture)
' add list item
DropDownList1.Items.Add(New ListItem(strTabTExt, Tab.TabID.ToString()))
Next
End If
End Sub
Private Sub PopulateStatusDropDown()
' get status collection
Dim StatusCollection As InstantASP.InstantKB.Collections.StatusCollection = _
InstantASP.InstantKB.Business.Status.SelectStatuses()
' get tab collection - pass userid for role based security
Dim TabCollection As InstantASP.InstantKB.Collections.TabCollection = _
InstantASP.InstantKB.Business.Tabs.SelectTabs(CurrentUser.UserID)
' ensure we have a tab collection
If Not TabCollection Is Nothing Then
' add empty item
DropDownList2.Items.Add("-")
' get current culture
Dim strCulture As String = GetCulture()
' enumerate through tabs
For intCount As Int32 = 0 To TabCollection.Count - 1
' get tab
Dim Tab As InstantASP.InstantKB.Components.Tab = TabCollection(intCount)
' get tab text
Dim strTabTExt As String = Tab.TabText(strCulture)
' get status collection for tab
Dim TabStatusCollection As InstantASP.InstantKB.Collections.StatusCollection = _
StatusCollection.FilterByTabID(Tab.TabID)
If Not TabStatusCollection Is Nothing Then
For intCount2 As Int32 = 0 To TabStatusCollection.Count - 1
' get status
Dim Status As InstantASP.InstantKB.Components.Status = _
TabStatusCollection.Item(intCount2)
' add list item
DropDownList2.Items.Add(New ListItem( _
strTabTExt + " - " + Status.Name, Status.StatusID.ToString()))
Next
End If
Next
End If
End Sub
Private Sub PopulatePriorityDropDown()
' get prioirty collection
Dim PriorityCollection As InstantASP.InstantKB.Collections.PriorityCollection = _
InstantASP.InstantKB.Business.Priorities.SelectPriorities()
' get tab collection - pass userid for role based security
Dim TabCollection As InstantASP.InstantKB.Collections.TabCollection = _
InstantASP.InstantKB.Business.Tabs.SelectTabs(CurrentUser.UserID)
' ensure we have a tab collection
If Not TabCollection Is Nothing Then
' add empty item
DropDownList3.Items.Add("-")
' get current culture
Dim strCulture As String = GetCulture()
' enumerate through tabs
For intCount As Int32 = 0 To TabCollection.Count - 1
' get tab
Dim Tab As InstantASP.InstantKB.Components.Tab = TabCollection(intCount)
' get tab text
Dim strTabTExt As String = Tab.TabText(strCulture)
' get status collection for tab
Dim TabPriorityCollection As InstantASP.InstantKB.Collections.PriorityCollection = _
PriorityCollection.FilterByTabID(Tab.TabID)
If Not TabPriorityCollection Is Nothing Then
For intCount2 As Int32 = 0 To TabPriorityCollection.Count - 1
' get priority
Dim Priority As InstantASP.InstantKB.Components.Priority = _
TabPriorityCollection.Item(intCount2)
' add list item
DropDownList3.Items.Add(New ListItem( _
strTabTExt + " - " + Priority.Name, Priority.PriorityID.ToString()))
Next
End If
Next
End If
End Sub
' -------------------------------------
' helpers
' -------------------------------------
' get InstantKB.NET user object
Private Function GetUser() As InstantASP.InstantKB.Components.User
Dim User As InstantASP.InstantKB.Components.User = Nothing
If System.Web.HttpContext.Current.User.Identity.IsAuthenticated Then
User = InstantASP.InstantKB.Business.User.SelectUser( _
System.Web.HttpContext.Current.User.Identity.Name)
Else
User = New InstantASP.InstantKB.Components.AnonymousUser
End If
Return User
End Function
Private Function GetCulture() As String
If CurrentUser.Culture <> "" Then
Return CurrentUser.Culture
End If
Return InstantASP.Common.Application.Settings.Instance().Culture
End Function
Private Sub BuildSearchEventArgsFromControls()
SearchEventArgs.Keywords = TextBox1.Text
If IsNumeric(DropDownList1.SelectedValue) Then
SearchEventArgs.TabID = CType(DropDownList1.SelectedValue, Int32)
End If
If IsNumeric(DropDownList2.SelectedValue) Then
SearchEventArgs.StatusID = CType(DropDownList2.SelectedValue, Int32)
End If
If IsNumeric(DropDownList3.SelectedValue) Then
SearchEventArgs.PriorityID = CType(DropDownList3.SelectedValue, Int32)
End If
End Sub
#End Region
#Region "Control Events"
Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
' setup search options
BuildSearchEventArgsFromControls()
' rebind data
BindData(GridView1.PageIndex, GridView1.PageSize, SearchEventArgs)
End Sub
Protected Sub DropDownList2_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles DropDownList2.SelectedIndexChanged
' setup search options
BuildSearchEventArgsFromControls()
' rebind data
BindData(GridView1.PageIndex, GridView1.PageSize, SearchEventArgs)
End Sub
Protected Sub DropDownList3_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles DropDownList3.SelectedIndexChanged
' setup search options
BuildSearchEventArgsFromControls()
' rebind data
BindData(GridView1.PageIndex, GridView1.PageSize, SearchEventArgs)
End Sub
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
' setup search options
BuildSearchEventArgsFromControls()
' rebind data
BindData(GridView1.PageIndex, GridView1.PageSize, SearchEventArgs)
End Sub
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging
BindData(e.NewPageIndex, GridView1.PageSize, SearchEventArgs)
End Sub
#End Region
End Class
After implementing the above code if you run the project (CTRL+F5) you'll notice we have basic search options pre-populated with the tabs, status' & priorities from within your InstantKB.NET database allowing you to select articles matching specific search critiria...

The code for this is very similar to our first example however we've added additional code to populate the various drop down lists & setup the SearchEventArgs object before passing this object to the pages BingData method. The SearchEventArgs objects contains many properties you can use to filter results by different critiria.
I hope this article has been helpful. You can download the source code shown here below. As always should you have any questions please don't hesitate to contact us or leave your commetns below.