IDataSourceParser
The IDataSource parser interface is used by some implementations of the IDataSource interface, such as the HTTPDataSource. It allows users to specify how they want the data to be handled. The HTTPDataSource is a generic HTTP datasource, which then uses the selected IDataSourceParser implementation to parse that data and return it according to the selected IDataSourceParser. Veva includes some IDataSourceParser implemententations, such as the HTMLParser which can be used for generic Web scraping, the XMLParser which is used to read data from XML based HTTP datasources, the RSSParser which reads items from standard RSS XML feeds via HTTP and then there are two JSON parsers available as well.
An example of a IDataSourceParser implementation could be a parser which reads data from a REST service via HTTP and performs some data manipulation/calculations and then generates a DataSourceItemsResult object with the calculated data, for display.
Interface declaration
public interface IDataSourceParser { Task<DataSourceItemsResult> ParseItemsAsync(object data); Task<DataSourceItem> ParseItemAsync(object data); string QueryKey { get; } }
Example
In this example, we have created a IDataSourceParser which expects a JSON document with this structure:
[
{'Name': 'Name of object 1','ValueA': 100, 'ValueB': 200},
{'Name': 'Name of object 2','ValueA': 100, 'ValueB': 200},
...
]
It will return a DataSourceItemsResult where the items is an array of records with the Name, ValueA and ValueB fields along with a new "SumOfAAndB" field which contains the sum of the ValueA and ValueB fields in the original feed.
public class Foo { public string Name { get; set; } public int ValueA { get; set; } public int ValueB { get; set; } } public class ExampleDataSourceParser : IDataSourceParser { public string QueryKey => ""; public async Task<DataSourceItem> ParseItemAsync(object data) { throw new NotImplementedException(); } public async Task<DataSourceItemsResult> ParseItemsAsync(object data) { DataSourceItemsResult result = new DataSourceItemsResult(); var deserializedData = JsonConvert.DeserializeObject<List<Foo>>(data.ToString()); var items = new List<DataSourceItem>(); items.AddRange(deserializedData.Select(x => new DataSourceItem() { Identifier = x.Name, Values = new Dictionary<string, object>() { { "Name", x.Name }, { "ValueA", x.ValueA }, { "ValueB", x.ValueB }, { "SumOfAAndB", x.ValueA + x.ValueB }, } })); result.Fields = new List<DataSourceField>() { new DataSourceField() { FieldType = DataSourceFieldType.String, Name = "Name", Title = "Name" }, new DataSourceField() { FieldType = DataSourceFieldType.Number, Name = "ValueA", Title = "Value A" }, new DataSourceField() { FieldType = DataSourceFieldType.Number, Name = "ValueB", Title = "Value B" }, new DataSourceField() { FieldType = DataSourceFieldType.Number, Name = "Total", Title = "The sum of A and B" } }; result.Items = items; result.TotalItems = items.Count; result.QueryKey = QueryKey; return result; } }
Registration
This is how the implementation is registered into the DI container in Veva, this should be done in your module config file (The class which implements IModule).
public void ConfigureServices(IServiceCollection services, IConfiguration configuration) { services.AddNamed<IDataSourceParser, ExampleDataSourceParser>(ServiceLifetime.Transient); }