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.
NoteOptimizely 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-languagecolumn. - 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\_SubmitTimeis not compatible with OData serializing. You should use$filterwithoutSYSTEMCOLUMN\_SubmitTimeand filter the data by code. - For implementation, writes the extension on top of the ServiceAPI to use its OAuth2 handling.
NoteIf 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.ServiceApiNuGet package with Visual Studio and rebuild the solution. -
Update the
EPiServer.ServiceApito latest version by running the following command in the Package Manager Console.update-package EPiServer.ServiceApi -
Update
appsetting.jsonto configClientIdandClientSecret"EPiServer": { "ServiceApi": { "RequireSsl": true, "ClientId": "cli", "ClientSecret": "cli" } }, -
Bind HTTPS for your site.
EPiServer.Forms.ServiceApidepends 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.ServiceApiis working.Before you can use the
ServiceApi, accesshttps://YourSite//EPiServer.Forms.ServiceApifrom 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– in Forms Service API 3.1.0] Del 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 about 2 months ago