Peter Hecke
Microsoft Corporation
July 2007
Applies to:
Microsoft Dynamics™ CRM 3.0
Requires:
Microsoft Dynamics CRM 3.0
Microsoft® Visual Studio® 2005
Summary
Do you have technical information stored in some data source
external to Microsoft Dynamics CRM that you want imported into Microsoft
Dynamics CRM as knowledge base articles? Perhaps you want to use a preferred
editing application to write content for knowledge base articles and then
import the content into Microsoft Dynamics CRM.
Use the information and code sample provided in this article to
write your own custom code to create and publish your target business
information as knowledge base articles using the Microsoft Dynamics CRM SDK. This
article describes how creating and publishing a knowledge base article differs
from creating instances of other entity types in Microsoft Dynamics CRM.
It is assumed that you have basic development experience with Microsoft
Visual C#® or Microsoft Visual Basic®, which run on the .NET Framework,
and existing knowledge of programming Microsoft Dynamics CRM through the Microsoft
Dynamics CRM SDK.
Download the sample code for this article: kbpublish.exe
The download contains both a Visual C# and a Visual Basic version
of the sample application.
Contents
Overview
This article describes how to programmatically create and publish
knowledge base articles in Microsoft Dynamics CRM. Although creating knowledge
base articles is similar to creating other instances of entity types in Microsoft
Dynamics CRM, there is a process that must be followed in order to publish the
article. The following sections of this article describe a knowledge base
article, the states that are part of its life cycle, and how to migrate an
article from an initial draft through publication.
The source code sample download that accompanies this article
provides a class containing basic methods that create and manipulate knowledge
base articles and templates. By using the supplied sample code, you can easily
manage knowledge base articles using the Microsoft Dynamics CRM SDK. By
extending the design of the sample code, you can provide a more robust and full
featured implementation.
A knowledge base article is a business entity in Microsoft
Dynamics CRM. The knowledge base article is typically used to provide
information which has value to and is shared by the employees of an organization.
For a Service organization, a knowledge base article typically provides a well
documented description and solution to a common problem. A knowledge base
article that contains the solution to a customer’s problem can be
e-mailed to the customer. For a non-service organization, the knowledge base
article can provide other useful information. Some examples of information that
can be stored in a knowledge base article include the following:
- Frequently Asked Questions (FAQs)
- Schematics
- Product user guides
- Data sheets
- Release schedules
An example knowledge base article is shown in figure 1.
Figure 1. A Knowledge Base article displayed in Microsoft
Dynamics CRM
Using the built-in Advanced Find feature of Microsoft Dynamics
CRM, you can search for relevant knowledge base articles in the Microsoft
Dynamics CRM database. Figure 2 shows an Advanced Find query which searches for
all knowledge base articles which have a subject of “Components”
and are published.
.jpg)
Figure 2. An Advanced Find query for a Knowledge Base article
Whereas you can interactively create and publish knowledge base
articles in the Microsoft Dynamics CRM Web application, sometimes you may have to
create and publish articles using the SDK. One example of this is when you have
existing documentation in some format stored in another data source, such as a
database, external to Microsoft Dynamics CRM. You could write custom code to
obtain that documentation and store it in Microsoft Dynamics CRM as one or more
knowledge base articles.
Another example is if you wanted to use a more full featured
editor than the one provided with Microsoft Dynamics CRM to create your knowledge
base articles and then import them into Microsoft Dynamics CRM through custom code.
TipThe Microsoft Dynamics CRM Web application
includes an editor for knowledge base articles. The editor enables you to
change fonts, styles, set indent levels, and create lists in the knowledge base
article content. However, because knowledge base articles are rendered as HTML,
by using the SDK you can add your own HTML code to knowledge base article
content beyond the scope that the editor supports.
Knowledge base article queues correspond with the internal
“state” of a knowledge base article. Figure 3 shows the knowledge
base article queues in the Microsoft Dynamics CRM user interface.
Figure 3. The Knowledge Base Article Queues
From a user’s point of view, the knowledge base article
exists in one of three queues. For a developer, the knowledge base article is
in one of three states. Those knowledge base articles that are in the Draft
queue are newly created, are being edited, or are being stored offline. Knowledge
base articles in the Unapproved queue are awaiting manager approval for
publication and have usually passed a technical review. Knowledge base articles
in the Published queue are available to be viewed by other Microsoft Dynamics
CRM users and are considered complete and accurate.
The following table shows the relationship between the queues, statuses,
and states.
| Queue name in Web application | Status in Web application | State in SDK |
| Draft | Draft | KbArticleState.Draft |
| Unapproved | Unapproved | KbArticleState.Unapproved |
| Published | Published | KbArticleState.Published |
You can create and publish a knowledge base article either through
the Microsoft Dynamics CRM Web application or by using the SDK. This article
describes the process from the perspective of the Microsoft Dynamics CRM SDK,
referring to the knowledge base article states instead of the queues shown in
the Web application. Figure 4 shows the process of
creating a knowledge base article and publishing it.
.jpg)
Figure 4. The process of creating and publishing an article
In the previous illustration, the newly created knowledge base article
is in a Draft state. To publish a knowledge base article, the state of the
article must be changed from Draft to Unapproved, and then from Unapproved to
Published. To delete a knowledge base article, its state must be either Draft
or Unapproved. The details of how to manage this process by using the SDK is
discussed in the Software Design and Implementation
section of this article. Sample code to create and publish knowledge base
articles using the SDK is provided in the download file that accompanies this
article.
Software Design and Implementation
The sample code provided with this article contains a custom knowledge
base Manager class. Knowledge base articles and
templates are typically created and manipulated using the SDK in a similar way
as any other entity instances in Microsoft Dynamics CRM. The scope of the Manager class is to manage a particular resource: knowledge
base articles and templates. There are methods to add an article or remove it
from the knowledge base, publish the article, or search for it in the database.
The methods in the Manager class only cover the basic
operations required to demonstrate the concepts discussed in this article. You
can extend the class to provide a richer and more robust programming model.
In addition to the Manager class, the
sample source code provides a Main method that creates
a new knowledge base article and then uses the Manager
class methods to perform some basic operations.
The kbarticle entity contains various
attributes that define the contents of the knowledge base article and its
relationship to other entities. Among these attributes are references to a subject
and knowledge base article template. These two entity records must exist in the
Microsoft Dynamics CRM database at the time when the knowledge base article is
created. Figure 5 shows knowledge base article creation and publication from a
developer’s point of view.
.jpg)
Figure 5. The process of creating and publishing an article
After creating an instance of a kbarticle
and populating its attributes, including the subject and template references
(relationships), the CrmService.Create method is called
to create the knowledge base article in the Microsoft Dynamics CRM database. This
newly created article now exists in a state of Draft. For the knowledge base
article to be published, its state must be changed to Unapproved and then to Published.
This state change is achieved by populating a SetStateKbArticleRequest
class instance with the required attributes and passing the instance as a
parameter to the CrmService.Execute method. Example
code that demonstrates this technique is provided later in this article.
Although it is not shown in the figure, you can also change the knowledge
base article’s state from Published to Unapproved and from Unapproved to Draft.
The naming of the methods of the Manager Class is consistent to
what you would see in other .NET libraries. Figure 6 shows the API design of
the Manager class, and the different class methods are
discussed in the following sections.
.jpg)
Figure 6. The custom Manager class
The Manager class constructor code is
shown here. The constructor stores the CrmService
reference that is passed to it in a private variable.
// CrmService Web service
private CrmService _service;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="service">The CrmService Web service.</param>
/// <exception cref="System.Exception">System.Exception</exception>
public Manager(CrmService service)
{
if (service != null)
_service = service;
else
throw new System.Exception("An invalid Microsoft Dynamics CRM Web service was specified.");
}
The following code contains methods that add a knowledge base
article to, or removes it from, the Microsoft Dynamics CRM database.
/// <summary>
/// This method adds the KB article to the database.
/// </summary>
/// <param name="article">A kbarticle instance containing title, subject,
/// and articleXML attributes defined.</param>
/// <returns>The Global Unique Identifier of the newly created article.</returns>
/// <exception cref="System.Exception">System.Exception</exception>
public Guid Add(kbarticle article)
{
if (article == null)
throw new System.Exception("An invalid article was specified.");
return _service.Create(article);
}
/// <summary>
/// This method deletes an existing article from the knowledge base.
/// The article must be in a Draft or Unapproved state in order to be deleted.
/// </summary>
/// <param name="entityname">The name of the entity to search for. The name can be
/// kbarticle or kbarticletemplate. Obtain the entity name from the
/// EntityName enumeration.</param>
/// <param name="articleID">The Global Unique Identifier of an existing article.</param>
/// <exception cref="System.Exception">System.Exception</exception>
public void Remove(string entityname, Guid articleID)
{
if (entityname == null || entityname == String.Empty)
throw new System.Exception("The entity name parameter is invalid.");
if (String.Compare(entityname, EntityName.kbarticle.ToString()) != 0)
{
if (String.Compare(entityname, EntityName.kbarticletemplate.ToString()) != 0)
throw new System.Exception("An unsupported entity name was specified.");
}
if (articleID == Guid.Empty)
throw new System.Exception("An invalid article ID was specified.");
_service.Delete(entityname, articleID);
}
You can overload the Add method to take a
kbarticletemplate type parameter so that knowledge base
article templates can be added to the database. The Remove
method also supports removing knowledge base article templates.
Changing a knowledge base article’s state puts the article
in the appropriate article queue when viewed in the Microsoft Dynamics CRM Web
application. The methods shown here change a knowledge base article’s
internal state to Unapproved or Published. The status reason is also set. You
can easily copy and modify one of these methods to create a Draft
method that sets the knowledge base article’s state to Draft.
/// <summary>
/// This method changes the state of an article to Unapproved. The
/// article must be in either a Draft state or a Published state.
/// </summary>
/// <param name="articleID">The Global UniqueIdentifier of an existing article.</param>
/// <exception cref="System.Exception">System.Exception</exception>
public void UnApprove(Guid articleID)
{
if (articleID == Guid.Empty)
throw new System.Exception("An invalid article ID was specified.");
SetStateKbArticleRequest request = new SetStateKbArticleRequest();
request.EntityId = articleID;
request.KbArticleState = KbArticleState.Unapproved;
request.KbArticleStatus = 2;
_service.Execute(request);
}
/// <summary>
/// This method changes the state of an article to Published. The
/// article must be in an Unapproved state for it to be published.
/// </summary>
/// <param name="articleID">The Global Unique Identifier of an existing article.</param>
/// <exception cref="System.Exception">System.Exception</exception>
public void Publish(Guid articleID)
{
if( articleID == Guid.Empty )
throw new System.Exception("An invalid article ID was specified.");
SetStateKbArticleRequest request = new SetStateKbArticleRequest();
request.EntityId = articleID;
request.KbArticleState = KbArticleState.Published;
request.KbArticleStatus = 3;
_service.Execute(request);
}
The Find method performs a query by
attribute search of the Microsoft Dynamics CRM database. The method returns the
GUID of an existing knowledge base article or knowledge base article template that
contains a specified title. Notice that, even though multiple results can be
returned from the query, only the first match is returned from the Find method.
/// <summary>
/// This method searches the Microsoft Dynamics CRM database for an
/// existing knowledge base article or knowledge base article template.
/// </summary>
/// <param name="entityname">The name of the entity to search for. The name can be
/// kbarticle or kbarticletemplate. Obtain the entity name from the
/// EntityName enumeration.</param>
/// <param name="title">The title of the article or template.</param>
/// <returns>The Global Unique Identifier of an existing article or template.</returns>
/// <exception cref="System.Exception">System.Exception</exception>
public Guid Find(string entityname, string title)
{
if (entityname == null || entityname == String.Empty)
throw new System.Exception("The entity name parameter is invalid.");
if (title == null || title == String.Empty)
throw new System.Exception("The title parameter is invalid.");
Guid id = Guid.Empty;
// Search the database for an article or template with a specific title.
QueryByAttribute query = new QueryByAttribute();
ColumnSet cols = new ColumnSet();
query.ColumnSet = cols;
query.EntityName = entityname;
query.Attributes = new string[] { "title" };
query.Values = new string[] { title };
if (entityname == EntityName.kbarticletemplate.ToString())
{
cols.Attributes = new string[] { "kbarticletemplateid" };
BusinessEntityCollection retrieved = _service.RetrieveMultiple(query);
// Only use the first entity found that matches the search criteria.
if (retrieved.BusinessEntities.Length > 0)
id = ((kbarticletemplate)retrieved.BusinessEntities[0]).kbarticletemplateid.Value;
}
else if (entityname == EntityName.kbarticle.ToString())
{
cols.Attributes = new string[] { "kbarticleid" };
BusinessEntityCollection retrieved = _service.RetrieveMultiple(query);
if (retrieved.BusinessEntities.Length > 0)
id = ((kbarticle)retrieved.BusinessEntities[0]).kbarticleid.Value;
}
else
throw new System.Exception("The entity name specified is not supported.");
return id;
}
Within a knowledge base article template, sections are used to
logically divide the information that is contained in a knowledge base article.
Each section contains a title followed by instructions or other information. Each
knowledge base article template contains at least one section. The default
templates that that are included with Microsoft Dynamics CRM define two or
three sections. Open a knowledge base article template in the Microsoft
Dynamics CRM Web application to see an example of this.
After instantiating a kbarticle, the articlexml attribute must be set to XML code that defines the
sections of the knowledge base article. The ConvertTo
method uses the supplied values for the description and
content attributes of the kbarticle
to construct a two section XML document, which is required for the standard knowledge
base article template that the sample code uses. The description and content is
stored as HTML code in a CDATA section within the XML document as shown here.
<articledata>
<section id="0">
<content>
<![CDATA[ <FONT color=#a31515 size=2><P>Lubricate and properly tension your
bicycle chain every 400 miles.</P></FONT>
]]>
</content>
</section>
<section id="1">
<content>
<![CDATA[ <FONT color=#a31515 size=2><P>The <a href="http://en.wikipedia.org/wiki/Bicycle_chain">chain</a> on your bicycle
needs routine maintenance to avoid chain failure down the road. Take your bike
to a bicycle shop to have the chain lubricated and adjusted every 400 miles.
You may be able to do the work yourself. Follow the instructions in the manual
that were included with your bicycle on how to lubricate and adjust the
chain.</P></FONT>
]]>
</content>
</section>
</articledata>
The following code sample shows the ConvertTo
method, which generates the XML.
/// <summary>
/// This method creates an XmlDocument from the description and content
/// attributes of a kbarticle. The XmlDocument is in the correct format
/// to be used as a kbarticle.articlexml attribute.
/// </summary>
/// <param name="article">An article with description and content attributes defined.</param>
/// <returns>An XmlDocument that contains the article's content.</returns>
/// <exception cref="System.Exception">System.Exception</exception>
public XmlDocument ConvertTo(kbarticle article)
{
if( article == null || article.description == null || article.content == null )
throw new System.Exception("An invalid article was specified.");
// Create a new XML document that contains an article data element.
XmlDocument document = new XmlDocument();
XmlElement articleData = document.CreateElement("articledata");
// Create the first section element that contains the article's description.
XmlElement section0 = document.CreateElement("section");
XmlAttribute attribute = document.CreateAttribute("id");
attribute.Value = "0";
section0.Attributes.Append(attribute);
XmlElement content = document.CreateElement("content");
content.AppendChild(document.CreateCDataSection("<FONT color=#a31515 size=2><P>" +
article.description + "</P></FONT>"));
section0.AppendChild(content);
articleData.AppendChild(section0);
// Create another section element that contains the article's main content.
XmlElement section1 = document.CreateElement("section");
attribute = document.CreateAttribute("id");
attribute.Value = "1";
section1.Attributes.Append(attribute);
content = document.CreateElement("content");
content.AppendChild(document.CreateCDataSection("<FONT color=#a31515 size=2><P>" +
article.content + "</P></FONT>"));
section1.AppendChild(content);
articleData.AppendChild(section1);
document.AppendChild(articleData);
return document;
}
The program’s Main method is
responsible for creating a new knowledge base article and exercising some of
the Manager class methods. An optional command line
argument is supported so that you can specify the name and TCP port of the Microsoft
Dynamics CRM server.
The Main method begins by configuring the
Microsoft Dynamics CRM Web service and creating a custom subject, although you
could use an existing subject. The kbarticle is created
as you would usually create any other instance of an entity in Microsoft
Dynamics CRM and in accordance to the programming methodology as documented in
the SDK. The Manager class is instantiated and its
various methods called to search for an existing knowledge base article
template, add the newly created knowledge base article to Microsoft Dynamics
CRM, and ultimately publish it. The code for the Main
method is shown here.
static void Main(string[] args)
{
// Set a default Microsoft Dynamics CRM server URL.
string serverUrl = "http://localhost";
// If the user has specified a server as a program argument
// use that one instead.
if (args.Length > 0)
serverUrl = String.Concat("http://", args[0]);
// Create and configure the CrmService Web service.
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.Url = String.Concat(serverUrl, "/MSCRMservices/2006/CrmService.asmx");
try
{
// Create a new subject for the article. You could also retrieve an
// existing subject from the Microsoft Dynamics CRM database.
subject s = new subject();
s.description = "Subjects related to bicycle maintenance";
s.title = "Bicycle Maintenance";
s.featuremask = new CrmNumber();
s.featuremask.Value = 1;
Guid subjectID = service.Create(s);
// Create an instance of the custom Knowledge Base Manager class.
Manager manager = new Manager(service);
// Create an instance of a knowledge base article.
kbarticle article = new kbarticle();
// Search for an existing article template in Microsoft Dynamics CRM.
article.kbarticletemplateid = new Lookup();
article.kbarticletemplateid.Value =
manager.Find(EntityName.kbarticletemplate.ToString(),
"Standard KB Article");
article.title = "Periodic Bicycle Chain Maintenance";
article.subjectid = new Lookup();
article.subjectid.Value = subjectID;
article.keywords = "bicycle, chain, maintenance";
article.description = "Lubricate and properly tension your bicycle chain every 400 miles.";
article.content = "The <a href=\"http://en.wikipedia.org/wiki/Bicycle_chain\">chain</a>
on your bicycle needs routine maintenance to avoid chain failure down the road.
Take your bike to a bicycle shop to have the chain lubricated and adjusted every
400 miles. You may be able to do the work yourself. Follow the instructions in the
manual that was included with your bicycle on how to lubricate and adjust the chain.";
// Convert the article to XML.
article.articlexml = manager.ConvertTo(article).InnerXml.ToString();
// Add the article to the knowledge base. New articles are added as a draft.
Guid articleID = manager.Add(article);
if (articleID != Guid.Empty)
{
// To publish an article, you must first unapprove it and then publish it.
manager.UnApprove(articleID);
manager.Publish(articleID);
}
Console.WriteLine("The article has been added to the Microsoft Dynamics CRM Knowledge Base.");
Console.WriteLine("Use the Microsoft Dynamics CRM Web application to view the Knowledge Base article.");
Console.WriteLine("Press <Enter> to delete all created entities...");
Console.ReadLine();
// Delete all entities created in this sample.
manager.UnApprove(articleID);
manager.Remove(EntityName.kbarticle.ToString(), articleID);
service.Delete(EntityName.subject.ToString(), subjectID);
}
catch (System.Web.Services.Protocols.SoapException e)
{
Console.WriteLine(e.Message + "\n" + e.Detail.InnerText);
Console.ReadLine();
}
catch (System.Net.WebException e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
An existing knowledge base article template is used in this code
sample when creating the knowledge base article. Although you can create a new knowledge
base article template using the SDK, this practice is discouraged. The recommended
method is to create a knowledge base article template by using the Microsoft
Dynamics CRM Web application. However, if you want to create your own custom knowledge
base article templates through the SDK, use one of the existing knowledge base article
templates as a guide to the type of information and the data format that is
required. You can find the existing templates in the KbArticleTemplateBase
table of the <organization>_MSCRM database on the
Microsoft Dynamics CRM server.
Additional
Information
This section lists sources of additional information about topics
discussed in this article.
For more information about programming Microsoft Dynamics CRM 3.0, see the
Microsoft
Dynamics CRM 3.0 SDK.