Introduction to the Managed Browser
The ManagedBrowser is an interface to the SmartSpace User Data Model (UDM) from .NET applications. It is a more powerful alternative to the UDMAPI interface, but unlike the latter is not accessible through web service calls. Instead a .NET application must reference the ManagedBrowser assembly.
The ManagedBrowser supports creating and deleting objects, querying and setting properties, and callback when data model properties change.
ManagedBrowser is available on both Windows and Linux.
Getting Started
Getting the ManagedBrowser NuGet package
You can download the
You can also find the ManagedBrowser.3.9.xxxx.nupkg package in the api\dotnet folder of your distribution directory.
Setting up the package source
Download the
ManagedBrowser on Windows
The ManagedBrowser is distributed as an x86 architecture assembly, not a MSIL or x64. Thus it can only be referenced from a product which also targets x86.
If you are using .NET 4.0 or higher, you need to enable the legacy activation policy.
For example, in your app.config:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
</startup>
You also need to set the platform target in the .csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="UbisensePlatform" Version="3-*" />
<PackageReference Include="ManagedBrowser" Version="3-*" />
</ItemGroup>
</Project>
Add ManagedBrowser.dll and UbisensePlatform.dll from the distribution as references in your project. You should now be able to construct an instance of the Ubisense.UDMAPI.ManagedBrowser class.
ManagedBrowser browser = new ManagedBrowser();
ManagedBrowser on Linux
The ManagedBrowser is available on Linux where it is distributed as an x64 architecture assembly. So you need to set the platform target in the .csproj file as follows:
<PropertyGroup> … <PlatformTarget>x64</PlatformTarget> … </PropertyGroup>
Debugging .NET Core Applications that use ManagedBrowser with the Visual Studio Debugger
The following work-around is required to get a .NET core application that uses the Ubisense ManagedBrowser API to run within the Visual Studio debugger. This doesn’t work out of the box with .NET Core 2.x because the Visual Studio debugger tries to start the 64-bit dotnet.exe, rather than the 32-bit dotnet.exe required by an x86 executable.
To override this behavior, the Directory.Build.targets file needs to be dropped into a folder in or above the project file. This ensures the correct executable is run.
Publishing your Code
When you publish your code, you must specify the correct runtime version with the publish command. These are:
-
Windows: dotnet publish -r win-x86
-
Linux: dotnet publish -r linux-x64
Objects and Names
Objects are represented in results as a string form including the object id and type. This is intended as an opaque identifier which can be used to refer to the object. For example:
04007zLfF_94Wzfm000IsG0000F:UserDataModel::Product
Most objects will also have a name, and the name can be retrieved
using the get_name
method.
var n = browser.get_name(cobj);
Console.WriteLine("{0} has name {1}", cobj, n);
If the object is not a known object, such as when it has been deleted, the result will be null.
Conversely, the object can be retrieved for a given name using get_object
.
var cobj2 = browser.get_object("Product", n);
Note that if the object of that name and type is not found, this method returns null.
Events
To receive events when properties change, first create a callback class which implements the IRowEvents
.
class MyCallback : IRowEvents
{
#region IRowEvents Members
public void data_inserted(string prop, List<string> row)
{
WriteRow("insert", prop, row);
}
public void data_removed(string prop, List<string> row)
{
WriteRow("remove", prop, row);
}
public void data_updated(string prop, List<string> before, List<string> after)
{
WriteRow("update from", prop, before);
WriteRow("update to", prop, after);
}
public void establish()
{
Console.WriteLine("establish");
}
public void schema_changed()
{
Console.WriteLine("schema changed");
}
#endregion
private void WriteRow(string desc, string prop, List<string> row)
{
Console.Write("{1} {0}:", desc, prop);
bool first = true;
foreach (var p in row)
{
if (!first) Console.Write(",");
Console.Write(p);
first = false;
}
Console.WriteLine();
}
};
Now set an instance of the class as the callback for the browser.
ManagedBrowser browser = new ManagedBrowser();
var cb = new MyCallback();
browser.set_event_callback(cb);
Now use add_property to specify which property change events to receive.
browser.add_property("name<Product>");
browser.add_property("[Custom]test_bool<Product>");
NOTE: If you expect the data model schema to change (specifically properties
or named types to be removed) then you should also periodically call
update_definitions
. Otherwise the browser only checks for updated
data model schema when queries are performed, so if your application
only responds to events, it would stop receiving any when the data
model schema changes.
Queries
The browser supports a number of queries of the data model.
Getting Objects
The set of objects of a given type can be retrieved using
get_named_objects
or get_named_objects_with_descendants
. The
first returns only objects exactly matching the given type. The
second returns objects which are of the given type or inherited from
that type. In either case the output is a dictionary mapping from
object to name.
Finding Types and Properties
To see the names of properties and types currently defined in the data
model, use the all_properties
and all_types
methods. Note that
types and properties include the namespace to which they belong, such
as [Offline]
or [Custom]
.
Each property row maps from a key to a value, where the key can be one or more columns, and the value is a single column. Simple properties have a single column in the key (the object on which the property is defined).
The types of a property can be queried:
- To get the types of each key column use
get_property_key_types
- To get the type of the value column use
get_property_value_type
Getting and Setting Property Values
Individual rows of a property can be retrieved using
get_property_value
, which takes the name of the property and a list
of strings as the key.
var cobj = browser.get_object("Product", n);
string val;
if (browser.get_property_value("[Custom]test_bool<Product>", new List<string> { cobj }, out val))
{
Console.WriteLine("{0} -> {1}", cobj, val);
}
This method returns true on success, or false on failure. Failure can be because the property is not known, or the types or length of the key parameter do not agree with the property definition.
The complete set of rows in a property can be retrieved using
get_property_values
, which returns a dictionary mapping from key to
value.
Dictionary<List<string>, string> rows;
browser.get_property_values("[Offline]entry_time<Product>", out rows);
foreach (var r in rows)
{
StringBuilder kb = new StringBuilder();
bool first = true;
foreach (var k in r.Key)
{
if (!first) kb.Append(",");
kb.Append(k);
first = false;
}
var s = r.Value;
var d = browser.convert_datetime(s);
Console.WriteLine("{0}: {1} = {2}", kb, r.Value, d.ToLocalTime());
}
This method returns false if the property is unknown.
Setting Properties
The value of a property can be set using set_property_value
, and can be removed using delete_property_value
.
var cobj = browser.get_object("Product", n);
browser.set_property_value("[Custom]test_bool<Product>", new List<string> { cobj }, "true");
...
browser.delete_property_value("[Custom]test_bool<Product>", new List<string> { cobj });
delete_property_value
if you intend to remove a row.The methods both return a bool, which is true on success, false on failure. Reasons for failure could include: the property named does not exist, or the passed parameters do not match the types in the property, or insufficient columns were passed for the key.
Converting Between Columns and Strings
Columns of type Object and Time are returned in a special string form, which can be converted to types compatible with the rest of the platform .NET API using the convert methods of the browser.
convert_object
: turns an object column into a Ubisense.UBase.UObjectconvert_datetime
: turns a date column into a UTC System.DateTimeconvert_string
: takes either a Ubisense.UBase.UObject or a System.DateTime and returns the column string equivalent