DataService. Updating records
Glossary Item Box
General provisions
The DataService web service of bpm'online is a RESTful (Representational State Transfer, REST) service. The RESTful data management interface does not require converting data to an external format, such as XML. In a simple RESTful service, each information unit is determined by a global Identifier such as URL. Each URL, in its turn, has a strictly specified format. This is not an optimal way to transfer large arrays of data.
Since the DataService web service is implemented based on the ServiceStack .NET framework, the data can be automatically converted into different file formats, such as XML, JSON, HTML, CSV and JSV. The data structure is determined by so-called data contracts. The data contracts used by DataService are listed in the "DataService web service" article.
UpdateQuery data contract
The UpdateQuery data contract is used for updating section records. The query data is transferred to DataService via HTTP, with the help of POST by the following URL:
// URL format of the POST query to DataService to update data. http(s)://[Bpm'online application address]/[Configuration number]/dataservice/[Data fromat]/reply/UpdateQuery // URL example of the POST query to DataService to update data. http(s)://example.bpmonline.com/0/dataservice/json/reply/UpdateQuery
The UpdateQuery data contract has a hierarchical structure with a number of nesting levels. In the bpm'online server core, it is represented by a UpdateQuery class of theTerrasoft.Nui.ServiceModel.DataContract namespace of the Terrasoft.Nui.ServiceModel.dll library of classes. For the hierarchical data structure of the UpdateQuery data contract can be conveniently viewed in JSON format:
{ "RootSchemaName":"[Root schema]", "OperationType":[Type of operation with record], "IsForceUpdate":[Force update], "ColumnValues":{ "Items":{ "Name of the added column":{ "ExpressionType":[Expression type], "Parameter":{ "DataValueType":[Data type], "Value":"[Column value]" } }... } }, "Filters":[Request filters] }
Primary properties of the UpdateQuery class and their possible values are available in table 1.
Table 1. UpdateQuery class properties
Property | Type | Notes | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
RootSchemaName | string | String that contains root schema name of added record object. | ||||||||||
OperationType | QueryOperationType |
Type of write operation. Specified as a QueryOperationType enumeration value of the Terrasoft.Nui.ServiceModel.DataContract name space. The QueryOperationType.Insert value is set for InsertQuery. Values of the QueryOperationType enumeration:
|
||||||||||
IsForceUpdate | bool | Indicates force update. If the value is true, the entity will be saved on the server even if column values have been modified. Default value: false. | ||||||||||
ColumnValues | ColumnValues | Contains collection of column values for the added record. The ColumnValues type is defined in the Terrasoft.Nui.ServiceModel.DataContract name space. | ||||||||||
Filters | Filters | Collection of query filters. The Filters type is defined in the Terrasoft.Nui.ServiceModel.DataContract name space. |
The ColumnValues class has a single Items property, defined as a collection of keys and values Dictionary<string, ColumnExpression>. The key is the string with the name of the added column. The value is an object of the ColumnExpression type, defined in the Terrasoft.Nui.ServiceModel.DataContract name space. General properties of the ColumnExpression class used when adding records are available in table 2.
Table 2. Primary properties of the ColumnExpression class
Property | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ExpressionType |
Type of expression that determines the value that the added column will contain. Specified with a value from the EntitySchemaQueryExpressionType enumeration of the Terrasoft.Core.Entities name space defined in the Terrasoft.Core class library. The EntitySchemaQueryExpressionType.Parameter value is set for InsertQuery. Values of the EntitySchemaQueryExpressionType enumeration:
|
||||||||||
Parameter |
Determines the value that the added column will contain. The Parameter type is defined in the Terrasoft.Nui.ServiceModel.DataContract name space. |
The Parameter class has a number of properties, only two of which are used for adding records (table 3).
Table 3. Primary properties of the Parameter class
Property | Description | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
DataValueType |
Type of data for the value that the added column will contain. Specified as a DataValueType enumeration value of the Terrasoft.Nui.ServiceModel.DataContract name space. Values of the DataValueType enumeration:
|
||||||||||||||||||||||||||||||||
Value |
The object that contains the value of the added column. Has the Object type. |
The Filters class is defined in the Terrasoft.Nui.ServiceModel.DataContract name space. For details on the properties of this class and its use, please see the "DataService. Data filtering" article.
NOTE An instance of the UpdateQuery class must contain a link to a correctly initialized instance of the Filters class in the Filters property. Otherwise, new column values from the ColumnValues property will be set for ALL section records. |
Case description
Create a console application that used DataService to update the "John Smith" record added in the example of the "DataService. Adding records" article. Add "j.smith@bpmonline.com" as the value in the [Email] column of this record.
Case realization
The complete source code for implementation of this case is available here.
Case implementation algorithm
1. Create and set up a C# application project
Using the Microsoft Visual Studio development environment (version 2012 Update 4 and up), create a Visual C# console application project and specify project name, for example, DataServiceUpdateExample. Set ".NET Framework 4.5" for the project property [Target framework].
In the References section of the project, add dependencies from the following libraries:
- System.Web.Extensions.dll – class library included in .NET Farmework;
- Terrasoft.Core.dll – library of base bpm'online server core classes. It can be found using the following path: [Bpm'online setup catalog]\Terrasoft.WebApp\bin\Terrasoft.Core.dll;
- Terrasoft.Nui.ServiceModel.dll — application service class library. It can be found using the following path: [Bpm'online setup catalog]\Terrasoft.WebApp\bin\Terrasoft.Nui.ServiceModel.dll;
- Terrasoft.Common.dll – library of base bpm'online server core classes. It can be found using the following path: [Bpm'online setup catalog]\Terrasoft.WebApp\bin\Terrasoft.Common.dll.
Add the "using" directives to the application source code file:
using System; using System.Text; using System.IO; using System.Net; using System.Collections.Generic; using Terrasoft.Nui.ServiceModel.DataContract; using Terrasoft.Core.Entities; using System.Web.Script.Serialization; using Terrasoft.Common;
2. Add fields and constants and field declarations to the source code
To access DataService features, add the following fields and constants to the application source code:
// Primary URL of bpm'online application. Must be repoaced with a custom one. private const string baseUri = @"http://example.bpmonline.com"; // Request string to the Login methid of the AuthService.svc service. private const string authServiceUri = baseUri + @"/ServiceModel/AuthService.svc/Login"; // Path string for the UpdateQuery. private const string updateQueryUri = baseUri + @"/0/DataService/json/reply/UpdateQuery"; // Bpm'online authentication cookie. private static CookieContainer AuthCookie = new CookieContainer();
Here, three string fields are declared. These fields will be used to form authentication query and read data queries execution paths. Authentication data will be saved in the AuthCookie field.
3. Add method that performs bpm'online application authentication
Authentication is required to enable access to the DataService for the created application.
Both the algorithm and example of implementation method, which contains query to AuthService.svc for user authentication, are available in the "Authenticating external requests to bpm'online services" article.
4. Add implementation of the record add query
Because the updateQueryUri constant declared earlier contains a path for sending data in the JSON format, sent data must be configured beforehand as a string that contains a JSON object that corresponds to the UpdateQuery data contract. This can be done directly in a string variable, although a much more secure and convenient way of doing this would be to create an instance of the UpdateQuery class, fill out its properties and then serialize it to a string. This can be done with the help of the following source code:
// Instance of the request class. var updateQuery = new UpdateQuery() { // Root schema name. RootSchemaName = "Contact", // New column values. ColumnValues = new ColumnValues() { // Key-value collection. Items = new Dictionary<string, ColumnExpression>() { // [Email] column. { // key. "Email", // Value — instance of object schema request class. // Configuration of [Email] column. new ColumnExpression() { // Type of expression of obkect schema query — parameter. ExpressionType = EntitySchemaQueryExpressionType.Parameter, // Query expression parameter. Parameter = new Parameter() { // Parameter value. Value = "j.smith@bpmonline.com", // Parameter data type — string. DataValueType = DataValueType.Text } } } } }, // Query filters. Filters = new Filters() { // Filter type — group. FilterType = Terrasoft.Nui.ServiceModel.DataContract.FilterType.FilterGroup, // Filter collection. Items = new Dictionary<string, Filter>() { // Filter by name. { // Key. "FilterByName", // Value. new Filter { // Filter type — comparison filter. FilterType = Terrasoft.Nui.ServiceModel.DataContract.FilterType.CompareFilter, // Comparison type — starts with expression. ComparisonType = FilterComparisonType.Equal, // Expression to check. LeftExpression = new BaseExpression() { // Expression type - schema column. ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn, // Path to column. ColumnPath = "Name" }, // Filtering expression. RightExpression = new BaseExpression() { // Expression type - parameter. ExpressionType = EntitySchemaQueryExpressionType.Parameter, // Expression parameter. Parameter = new Parameter() { // Parameter data type - text. DataValueType = DataValueType.Text, // Parameter value. Value = "John Smith" } } } } } } }; // Serialization of update query class instance in a JSON string. var json = new JavaScriptSerializer().Serialize(updateQuery);
Here, an instance of the UpdateQuery class is created. In the ColumnValues property, the "j.smith@bpmonline.com" value is set for the [Email] column. To apply this value to a specific record or group of records, specify a link to a correctly initialized Filters class in the Filters property. In this case, a single filter is added to the filters collection to select only records that have the "John Smith" value in the [Full name] column.
The next step is to execute DataService POST-query. To do this, create an instance of the HttpWebRequest class, fill its properties and connect the string with the JSON object created earlier then execute the DataService query and process its result. To do this, add the following source code:
// Converting a JSON object string to a byte array. byte[] jsonArray = Encoding.UTF8.GetBytes(json); // Creating an insrance of HTTP request. var updateRequest = HttpWebRequest.Create(updateQueryUri) as HttpWebRequest; // Defining a request method. updateRequest.Method = "POST"; // Determining type of request content. updateRequest.ContentType = "application/json"; // Adding authentication cookie received earlier to a request. updateRequest.CookieContainer = AuthCookie; // Set length for request content. updateRequest.ContentLength = jsonArray.Length; // Plase a JSON-object to request content. using (var requestStream = updateRequest.GetRequestStream()) { requestStream.Write(jsonArray, 0, jsonArray.Length); } // Executing HTTP request and getting a response from server. using (var response = (HttpWebResponse)updateRequest.GetResponse()) { // Displaying response in console. using (StreamReader reader = new StreamReader(response.GetResponseStream())) { Console.WriteLine(reader.ReadToEnd()); } }
The complete source code for implementation of this case is available here.