Forms Service API
The Optimizely Forms Service API depends on the Optimizely Service API and helps a developer access form data like submission and metadata.
Note
Optimizely Forms is only supported by MVC-based websites and HTML5-compliant browsers.
The Forms.ServiceAPI
has the following attributes:
- Exposes RESTful API for reading data of a form.
- If you specify
neededLanguage
, only expose data whereSYSTEMCOLUMN-language="neededLanguage";
you do not need to show theSYSTEMCOLUMN-language
column. - If you do not specify
neededLanguage
, show data for all languages, and also showSYSTEMCOLUMN-language
.
- If you specify
- Supports CSV, XML, XLSX, and JSON formats.
- Supports pagination.
- Compatible with OData.
- $filter defined by OData can be used to filter onSYSTEMCOLUMN\_SubmitUser and SYSTEMCOLUMN\_FinalizedSubmission
. For example:Âhttp://localhost:56908/EPiServer.Forms.ServiceApi/GetFormData(Id=114,Language=null)?$filter=SYSTEMCOLUMN_SubmitUser
.
TheSYSTEMCOLUMN\_SubmitTime
is not compatible with OData serializing. You should use$filter
withoutSYSTEMCOLUMN\_SubmitTime
and filter the data by code. - For implementation, writes the extension on top of the ServiceAPI to use its OAuth2 handling.
Note
If you enable Allow Exposing Data Feeds in a form container, allowed credentials can fetch data with the ServiceAPI.
Work with the API
EPiServer.Forms.ServiceApi
is based on EPiServer.ServiceApi
.
-
Install theÂ
EPiServer.Forms.ServiceApi
 NuGet package with Visual Studio and rebuild the solution. -
Update the
EPiServer.ServiceApi
to latest version by running the following command in the Package Manager Console.update-package EPiServer.ServiceApi
-
Update
appsetting.json
to configClientId
andClientSecret
"EPiServer": { "ServiceApi": { "RequireSsl": true, "ClientId": "cli", "ClientSecret": "cli" } },
-
Bind HTTPS for your site.
EPiServer.Forms.ServiceApi
depends onEPiServer.ServiceApi
, which requires using https for consuming APIs, so you need go to IIS and bind https for your website. -
Verify that
EPiServer.Forms.ServiceApi
is working.Before you can use the
ServiceApi
, accesshttps://YourSite//EPiServer.Forms.ServiceApi
from a browser. If it returns JSON like this:...then it is working. If it does not return anything, re-install nuget then try again
-
Grant permission for the Config user to use
ServiceApi
.- Go to the admin view > Config > Security > Permissions for Functions.
- Add the user or group to the EPiServerServiceApi Read Access right. This user is for authenticating when you consume the
ServiceApi
.
- Implement OAuth2 client to access the service.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
namespace EPiServer.Forms.ServiceApi.WebTest {
public class OAuth2Client {
private string _baseUrl, _username, _password, _accessTokenUri;
public OAuth2Client(string baseUrl, string username, string password, string accessTokenUri) {
_baseUrl = baseUrl;
_username = username;
_password = password;
_accessTokenUri = accessTokenUri;
}
public string GetData(string uri, string accessToken) {
using(var client = new HttpClient()) {
client.BaseAddress = new Uri(_baseUrl);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = client.GetAsync(uri).Result;
if (response.StatusCode == HttpStatusCode.OK) {
var content = response.Content.ReadAsStringAsync().Result;
return content;
}
}
return string.Empty;
}
public string DeleteData(string uri, string accessToken, int formsId, IEnumerable<string> recordIds) {
using(var client = new HttpClient()) {
client.BaseAddress = new Uri(_baseUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var content = JsonConvert.SerializeObject(new {
Id = formsId,
SubmissionIds = recordIds
});
var postContent = new StringContent(content, Encoding.UTF8, "application/json");
var response = client.PostAsync(uri, postContent).Result;
return response.StatusCode.ToString();
}
}
public string GetAccessToken() {
var token = string.Empty;
using(var client = new HttpClient()) {
client.BaseAddress = new Uri(_baseUrl);
var fields = new Dictionary<string, string> {
{
"grant_type",
"client_credentials"
},
{
"client_id",
_username
},
{
"client_secret",
_password
},
{
"scope",
"epi_service_api"
}
};
var response = client.PostAsync(_accessTokenUri, new FormUrlEncodedContent(fields)).Result;
if (response.StatusCode == HttpStatusCode.OK) {
var content = response.Content.ReadAsStringAsync().Result;
token = (string) JObject.Parse(content).GetValue("access_token");
}
}
return token;
}
}
}
You can use the OAuth2Client class to access the service to get data. The service exposes the following methods:
GetFormsInfo
– Gets forms in the system. Accept language as a parameter; if the language parameter is null, it returns form information in the master language. The requesting user must have read access to the form to get data.GetFormData
– Fetches posted data of a specified form. You need to specify form id and language as parameters; language can be null, which returns data from all languages.GetFieldMapping
– Gets mappings between field name and their friendly name. You need to specify form ID and form language.DeleteFormData
– [New in Forms Service API 3.1.0] Deletes posted specified form data. You need to specify form Id and SubmissionIds as parameters.
To invoke DeleteFormData
action, use a POST request and JSON data format for the parameters in the request body. Example:
The service is compatible with OData 8.0. The following example shows how to use these methods.
private const string AccessTokenURI = "/api/episerver/connect/token";
private const string FormDataURI = "/EPiServer.Forms.ServiceApi/GetFormData(Id={0},Language=null)?$top=10";
private const string FormMappingURI = "/EPiServer.Forms.ServiceApi/GetFieldMapping(Id={0},Language=null)";
private const string FormsInfoURI = "/EPiServer.Forms.ServiceApi/GetFormsInfo(Language=null)";
private const string FormsDeleteURI = "/EPiServer.Forms.ServiceApi/DeleteFormData";
private static readonly string Username = ConfigurationManager.AppSettings["username"]; // clientId added to access ServiceApi on step 3
private static readonly string Password = ConfigurationManager.AppSettings["password"]; // clientSecret added to access ServiceApi on step 3
private static readonly string SiteUrl = ConfigurationManager.AppSettings["siteUrl"]; // ex: https://vnwks30:17005/
………………………………………………………………………………………………………………………………….
protected void FetchData_Click(object sender, EventArgs e) {
if (string.IsNullOrEmpty(FormId.Text)) {
return;
}
// for request to https site
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate {
return true;
};
var oAuthClient = new OAuth2Client(SiteUrl, Username, Password, AccessTokenURI);
var accessToken = oAuthClient.GetAccessToken();
var formsInfo = oAuthClient.GetData(FormsInfoURI, accessToken);
var mappings = oAuthClient.GetData(string.Format(FormMappingURI, FormId.Text), accessToken);
var data = oAuthClient.GetData(string.Format(FormDataURI, FormId.Text), accessToken);
// get the first record return from above function and delete it
if (data != null) {
var dataObj = JObject.Parse(data);
var firstId = dataObj["value"].First["Id"];
var recordIds = new List<string> {
firstId.ToString()
};
var deleteFirstRecord = oAuthClient.DeleteData(FormsDeleteURI, accessToken, int.Parse(FormId.Text), recordIds);
}
// delete all records
//var dataObj = JObject.Parse(data);
//var recordIds = new List<string>();
//foreach (var obj in dataObj["value"])
//{
// recordIds.Add(obj["Id"].ToString());
//}
//var deleteAllRecord = oAuthClient.DeleteData(FormsDeleteURI, accessToken, int.Parse(FormId.Text), recordIds);
}
Updated 7 months ago