Getting started

The .NET Editor libraries make it super quick for you to provide complex CRUD based web applications to end users. In order to achieve this we need to introduce the basic concepts of how the libraries operate and how you can use the interfaces that they provide to access your own databases. This page summarises how the Editor libraries operate and the concepts involved in using them.

Concept

It is important to understand the big picture of the approach the Editor .NET libraries take for interfacing between the database and the client-side DataTable / Editor before delving into the detail of how to actually read and write data.

The libraries provide an Editor class, a instance of which is created and will relate, primarily, to a single SQL table which it will read and write data from and to.

The Editor instance is then instructed about the database table columns that it should operate on and how. These columns are used to populate both the DataTable and Editor, and Editor has the ability to write to them. Fields from additional tables can also be included through the use of join statements.

Finally the data being sent by the client side is processed. There are four basic request types that DataTables and Editor can make:

  • Read - Get the data to display
  • Create - Create a new row of data
  • Edit - Update an existing row with changed data
  • Remove - Delete one or more rows from the database

The Editor class will automatically detect which of these four requests are being made and handle it correctly for you without adjustment. The data resulting from the request is then sent back to the client to it to complete the processing.

Basic initialisation

The first step to using the Editor libraries in any project is to include a reference to the DataTables.dll, which provides all the classes and methods required. You can do this in Visual Studio by right clicking on the References option in your project's Solution Explorer. From the context menu select the Add Reference option to open a dialogue box. Using the Browse option navigate to where you unzipped the Editor download package and locate the DataTables.dll file. Select and then click the Add button.

To complete the installation, add a using statement to the files where you will be using the Editor components (typically the model and controller):

using DataTables;

MVC

Editor can use the MVC model that is common in many other parts of the .NET framework. Using MVC you define a model that describes the structure of the data for each row in the table, while the controller acts upon the data given to it, processing the data as described by the model.

Model

The Editor model describes the data that is to be read from the database, the JSON structure for sending the data to the client-side and also the parameters that Editor submits when editing data. This is done with a simple class that contains the names of the database properties and their types. For example:

public class StaffModel
{
    public string   first_name { get; set; }
    public string   last_name { get; set; }
    public string   position { get; set; }
    public string   email { get; set; }
    public string   office { get; set; }
    public int      extn { get; set; }
    public int      age { get; set; }
    public int      salary { get; set; }
    public string   start_date { get; set; }
}

Please note that the model's data structure is used both for representation of the data from the database and the JSON data sent to the client-side for each row. This means that the data types used must be directly applicable to JSON as well as the database. In practice this means that string, int and Decimal are the data types that should be used. Other data forms such as DateTime fields should be given as a string, which Editor's libraries will convert automatically.

Joins

Data obtained from multiple tables (joined data) can also be described using a model, in this case with nested classes. A nested class is used for each table that data is to be read from with the properties of the nested class describing the fields to be read from that table. The nested class name must match the name of the table (which is why the example below uses lower case class names - it matches the table name!).

When using a model to describe the structure of joined tables the LeftJoin() method must still be used in the controller to define the actual join logic. Please refer to the join documentation for further details.

The example below uses data from two tables (users and sites), with each nested class defining the columns to read from the table:

namespace WebApiExamples.Models
{
    public class JoinModel
    {
        public class users
        {
            public string first_name { get; set; }
            public string last_name { get; set; }
            public string phone { get; set; }
            public int site { get; set; }
        }

        public class sites
        {
            public string name { get; set; }
        }
    }
}

Attributes

The properties in the model match the database column names, but there are a number of custom attributes that can also be used to modify the behaviour of each field:

  • EditorHttpName( string ) - Define the HTTP name for this property. This is used in the JSON data and the submitted form data. Although it doesn't provide much in the way of security, it does mean that your database column names don't need to be exposed on the client-side if you would prefer not to have that information external to your application.
  • EditorTypeError( string ) - If a type error occurs and the data read from the database or the submitted form data cannot be assigned to the data type given for the property in question Editor will generate an error. The text of that error can be given using this attribute.

As an example, the following property makes use of both attributes:

[EditorTypeError("Age must be an integer")]
[EditorHttpName("user_age")]
public int age { get; set; }

Controller

Where the model defines the data structure, the controller processes it. An Editor instance is constructed using:

new Editor( db, table, pkey="id" );

Where:

  • db is an instance of the Database class, which connects to the database
  • table is the table name to operate on.
  • pkey is an optional parameter that specifies the primary key of the table - the default is id. This option can also be given as a string array to an overloaded constructor (see below).

The Database class can be initialised in a number of different ways (refer to the Editor .NET API reference documentation for full details):

  • new Database(string, string)
  • new Database(string, DbConnectionStringBuilder)
  • new Database(string, DbConnection)

In the example package a database instance is created in each individual controller using a connection string.

Compound keys

As of Editor 1.6 the .NET libraries support compound keys: a key which is made up from the data in two or more table columns, rather than just a single column as used in many tables. To use a compound key, simply pass the primary key information into the third parameter for the Editor constructor as an array:

new Editor( db, "visitors", new []{"visitor_id", "visit_date"} );

No special configuration is required on the client-side to support compound keys, however, when creating new rows you must submit the data for the columns that make up the compound key (an error will be shown otherwise). Editor cannot currently read information that is generated by the database. If you need to set a server-side computed value (e.g. current time), use the Field.SetValue() method to set the value. This limitation is due to the database engines that Editor currently supports.

Chaining

Like the Editor Javascript API the .NET Editor API is fully chainable, allowing potentially complex code to be expressed succinctly. The majority of the methods that Editor and its child classes provide are chainable - i.e. they return the instance that you are working with. Consider for example:

$editor = new Editor( Db, 'staff' );
$editor.Fields( ... );
$editor.Process( ... );
DtResponse data = $editor.Data();

Using chained style, the above code block can be rewritten as:

DtResponse dt = new Editor( Db, 'staff' );
    .fields( ... )
    .process( ... )
    .data();

Using a chained style of coding is not required, although you will see it used in this documentation and the examples Editor comes with.

Fields

Once the Editor instance has been created and configured for what database table it should read from, it needs to be instructed what fields it should access on that table. This is can be done through the Model<T>() and Field() methods.

The Model<T>() method will accept an Editor model, as described above, as the data type and Editor will automatically process the model, adding fields as appropriate.

In addition to using the mode, the Field() method can be used to add additional instructions to individual fields (validators and formatters for example). This is done by passing the method a Field class instance.

done through the Fields() method which is passed Field class instances. Like the Editor class these are constructed using new Field() and the parameter given is the name of the column to read / write data, and also the name that will be used to return the data to DataTables and Editor. The fields() method can take as many field instances as you wish to define and can also be called multiple times to add additional fields.

In the example below the Editor instance is configured with the model defined above and the first_name field has simple validation attached to it:

new Editor( db, 'staff' )
    .Model<StaffModel>()
    .Field( new Field( 'first_name' ).Validator( Validation.NotEmpty() ) );

Field instances provide validation and formatting options as well as simple get / set options. Please refer to the documentation for sections for detailed information.

Data processing

When DataTables and Editor make a request to the server to get or update data, they send the data using HTTP parameters (POST is the default for Editor). This information can be obtained in your application added passed through to the Editor class for processing (use [FromBody] in Web API projects and Request.Form in MVC projects).

The data is acted upon by using the Process() method of the Editor class, with the data sent from the client being passed into it. At this point the Editor instance will perform whatever action the client-side has asked of it - be it to create a new row, update and existing row, etc. These actions will be automatically detected.

To continue the example above (without the validation for brevity), if we add a Process() method call we now have (this is MVC style):

new Editor( db, 'staff' )
    .Model<StaffModel>()
    .Process( Request.Form );

Return data

The final step is to send the data back to the client for it to process (e.g. display an error message if validation failed or redraw the table with the updated data if everything was successful). The data sent back to the client is in the JSON data format and again the Editor class will set this up automatically for you. The Data() method of the Editor class will return a DtResponse data type which can be passed through the JSON() method of both the Web API and MVC controllers to create the JSON.

A completed controller might be as simple as:

DtResponse response = new Editor( db, 'staff' )
    .Model<StaffModel>()
    .Process( Request.Form )
    .Data();

return Json(response);

And that's it! That is all that is required on the server-side, when using the Editor .NET libraries to add read / write ability to your database table. Additional fields can be trivially added using the model and other tables also setup for editing.

The next step is to add validation to your fields to ensure that the data sent is the data you expect.