Strongly Typed Ektron Smart Forms

Unfortunately, Ektron still doesn’t allow for strongly typed access to smart forms out of the box. However, that doesn’t mean you’re stuck using XSLT or parsing the XML. Some time ago, Bill Cava hosted a webinar titled Ektron Content Types that explained how to gain strongly typed access to smart forms by serializing the XML into a .NET class. It’s a great webinar, but a few things were left out, so I figured I’d include some instruction in a little more detail (mainly for my own reference).

Step 1: Getting the Smart Form XSD

Assuming you’ve already created your smart form, the next step is to get its XSD, or XML Schema Definition. To do this, click the XSD icon in the smart form designer toolbar. Now, copy the content to a plain text file, and save it as MySchema.xsd (obviously, replace MySchema with something relevant to your smart form — this will become the .NET class name also).

Step 2: Creating the .NET Class from Your XSD

Visual Studio comes with an application called xsd.exe, which you can use to automatically generate your .NET class from the XSD. If you don’t have or can’t find xsd.exe, there are online services that can do this as well (e.g. http://www.bware.biz/DotNet/Tools/CodeXS/WebClient/GenerateInput.aspx). Assuming you’re using xsd.exe, let’s create a .bat file and add the following to it (if you aren’t familiar with batch files, just open Notepad, type the code below and save as xsd.bat):

SET ROOT=C:\"Program Files (x86)"\"Microsoft SDKs"\Windows\"v8.0A"\bin\"NETFX 4.0 Tools"\
SET XSDPATH=C:\Users\username\Desktop\
SET XSDFILE=%1
SET NAMESPACE=%2

%root%xsd %XSDPATH%%XSDFILE% /classes /language:CS /namespace:%NAMESPACE% /outputdir:%XSDPATH%

Make sure to update XSDPATH to the path where you saved your XSD file from the last step (or move your file to the desktop). Also the ROOT path may be different for you depending on where your xsd.exe is located. Update it accordingly.

Now, open a command prompt (Windows key + R, type cmd, and press Enter), type the following, and press Enter:

cd C:\Users\username\Desktop

Note: If you saved your xsd.bat file somewhere other than the desktop, cd into that directory instead of the above.

Now type the following, making sure to replace “MySchema.xsd” with the name of your XSD file and “Some.Namespace” with your own custom namespace:

xsd.bat MySchema.xsd Some.Namespace

After the commands from the batch file are done, you should have a new .cs file in the same folder as your XSD file.

Step 3: Update the .NET Class

Although xsd.exe creates your .NET class for you, there are some changes you’ll need to make that weren’t mentioned in the Ektron webinar. First, you’ll want to change the following, which should appear near the top of the .cs file:

[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
    public partial class root {
        ...
    }

to this:

[System.Xml.Serialization.XmlRootAttribute(Namespace="", ElementName="root", IsNullable=false)]
    public partial class MySchema {
        ...
    }

Notice that we added ElementName="root", and we changed the class name from “root” to one better fitting our class. If our smart form was named “Book,” for example, we’d have chosen “Book” for the name of the class.

Now move the .cs file to your website’s AppCode folder, or wherever it fits best in the architecture of your website.

Step 4: Using the ContentTypeManager<T> and ContentType<T> Classes

Download Ektron’s source code for the ContentTypeManager and ContentType classes, and copy the ContentType.cs file to your AppCode directory (or wherever applicable). The webinar does a good job of explaining how to use ContentTypeManager and ContentTypes, so I won’t go into detail with their usage. Here’s some sample code to get you started:

ASPX

<asp:Repeater ID="MyRepeater" runat="server">
    <ItemTemplate>
        <p><%# Eval("SmartForm.Property") %></p>
    </ItemTemplate>
</asp:Repeater>

ASPX.CS

long folderId = 32; // Folder containing our smart form content
ContentTypeManager<MySchema> mgr = new ContentTypeManager<MySchema>();
Criteria<ContentProperty> criteria = new Criteria<ContentProperty>();
criteria.AddFilter(ContentProperty.FolderId, CriteriaFilterOperator.EqualTo, folderId);
List<ContentType<MySchema>> items = mgr.GetList(criteria);

MyRepeater.DataSource = items;
MyRepeater.DataBind();

Step 5: Updating the .NET Class for Rich Text and Other Complex Types

Another problem, not mentioned in the webinar, that you’re likely to run into is rich text fields and other smart form data types that don’t map to a standard .NET type. I’ll explain how to handle rich text, and figuring out the others should be self explanatory afterward.

Basically, what happens is that your .NET class will contain new types for anything that it doesn’t understand (i.e. anything other than String, DateTime, Int32, etc.). One of these types is “rich”, which it creates for rich text boxes. Search for the following in your MySchema.cs file:

public partial class rich {
    ...
}

What we want is for the “rich” type to return a string representation of the nodes it contains. To do this, we need to override its ToString() method. Add the following directives at the top…

using System.Text;
using System.Xml;

and add the following after the “rich” class’s field declarations:

public override string ToString()
{
    StringBuilder sb = new StringBuilder();

    foreach (XmlNode item in this.anyField)
    {
        sb.Append(item.OuterXml);
    }

    return sb.ToString();
}

Use the same approach for other Ektron smart form types that don’t match up to a .NET type.

At this point, you should have everything you need. Enjoy!

6 thoughts on “Strongly Typed Ektron Smart Forms”

  1. Is there a way to use this to search inside groups / sub items by chance? I can access the top level information in this case anything in the elements.

    Here is an example of the XML Layout Currently

    one
    sub street

    Name
    101 any street

    Second Name
    101 any street

Leave a Reply

Your email address will not be published. Required fields are marked *