Realm Mobile Database
is an open source project that has quickly become very popular, especially among mobile developers. It’s an alternative to SQLite and it’s a way to store complex data in a permanent way, pretty much like you would do with a regular database. Some of the advantages of this technology are that:
Like SQLite, it doesn’t need a “man in the middle” service (DBMS) to talk with the database (like SQL Server, Oracle, MySQL, etc.), but the application has direct access to it, making it a perfect match for mobile and simple applications.
It’s based on an object oriented model so, similarly in a way you do when you work with technologies like Entity Framework, you don’t have to write manual SQL queries to perform operations but you can keep working with classes, objects and powerful manipulation languages like LINQ.
It’s cross-platform, so you can share your database with the vast majority of platforms on the market.
It supports UI notifications out of the box, so the user interface of your application can be automatically updated every time the data in the database changes.
Why I’m talking about this technology in the AppConsult blog? Because the developer team behind Realm has recently announced support for .NET and Portable Class Libraries, which means that now you can use a Realm database also in Xamarin and Windows desktop applications. Can you see the direction where my post is going? As you’ll probably know if you have followed all the posts so far about the Desktop Bridge, there are some requirements that a converted desktop app must respect since:
A converted app needs to always run in user mode, you can’t require the user to have administrative rights in order to use the app or parts of it.
The deployment of a converted app is a “one click” procedure: you press an Install button (like when you use the Store), you wait for the package to be downloaded and installed and then you launch it.
As such, some scenarios that would require a more complex configuration environment (like installing a SQL Server instance to handle a database) aren’t supported. When we’re talking about the Desktop Bridge, technologies like SQLite or Realm Mobile Database are just perfect: the database is stored in a single file and it’s directly accessed by the application, so we can simply deploy it in any folder of the computer and let the application read and write from it, without having to install any particular service.
There’s a lot of documentation on the official website
that covers how to use Realm in a .NET application, including all the advanced (like encryption and synchronization) and corner case scenarios. In this post I would like to focus on the basic usage of the Realm Mobile Database and how you can leverage it in a desktop app converted using the Desktop Bridge, since there are some important caveats to consider.
For the purpose of this post, we’re going to create a simple WPF app that will allow us to:
Create a new database to store a list of customers.
Add some customers to the database.
Retrieve the list of customers stored in the database.
Update the info about one of the customers stored in the database.
Let’s start!
Configure Realm Mobile Database for the Desktop Bridge
Let’s start by opening Visual Studio and by creating a new WPF project, which you can find by following the path
File –> New project –> Templates –> Visual C# –> Windows Classic Desktop –> WPF App (.NET Framework)
. Make sure to choose at least .NET 4.6.1, since it’s the minimum version supported by the Desktop Bridge. Adding support to Realm Mobile Database is easy, since the team has released it as a NuGet package: right click on the WPF project, choose
Manage NuGet Packages
and look for and install the package identified by the
Realm
name.
By default, using Realm is quite easy: you can use the
Realm
class (included in the
Realms
namespace) and call the static method
GetInstance()
to get a reference to the database, which you will need later to perform all the standard CRUD operations (adding / removing / updating / reading an item). As such, the initialization code could be as easy as the following one:
private void InitializeRealm()
{
var realm = Realm.GetInstance();
}
However, when it comes to an app converted with the Desktop Bridge, this approach may have a downside. If you’ll try to execute it, you will notice that, by default, the database will be created in the
Documents
folder of the user. You will find, in fact, three new elements in this library:
The main database, which is a file called
default.realm
.
A lock file, used to handle concurrent operations, which is a file called
default.realm.lock.
A folder used to manage the database, called
default.realm.management
.
This scenario is absolutely supported also by a converted desktop app: since it’s executed with the
runFullTrust
permission, it has the chance to read and write folders in the
Documents
folder of the user without problems (since it’s a folder which doesn’t require admin rights to be accessed). So, why I’m saying that using the default approach can be a downside? One of the benefits of the Desktop Bridge compared to a traditional desktop app is that it offers a cleaner deployment experience, in terms of install / uninstall / upgrade operations. As such, storing the database of the application in the
Documents
library isn’t a great idea, because it’s the kind of user generated content that doesn’t make sense without the application that has created it: a regular user won’t know what to do with a
default.realm
file after he has uninstalled your application. Wouldn’t be better to leverage the AppData folder provided by Windows for this scenario? Additionally, thanks to the file system redirection provided by the Desktop Bridge, storing the database in the AppData folder would mean that, when the user will decide to uninstall your app, also the database will be removed, without leaving unnecessary files on the user’s disk.
We can achieve this goal thanks to a class called
RealmConfiguration
, that we can pass as parameter of the
GetInstance()
method and that we can use to customize the configuration of the database. One of the configurable parameters is exactly the path of the database. Here is a complete sample initialization code:
RealmConfiguration config = new RealmConfiguration(file);
realm = Realm.GetInstance(config);
}
We’re using the standard .NET APIs to get access to the local AppData folder of the user (thanks to the enumerator
Environment.SpecialFolder.LocalApplicationData
, which represents the %LOCALAPPDATA% system variable). Inside this special folder, we create sub folder with the name of our application (in this case,
RealmDesktop
), where we’re going to store the database. The first part of the code is pretty straightforward: if the app is running for the first time, the
RealmDesktop
folder doesn’t exist yet, so we need to create it first. Then we combine the path of the folder with the name of the database (in our case, we keep the standard name
default.realm
) and we pass it as initialization parameter of a new
RealmConfiguration
object. Then we can leverage the same
GetInstance()
method offered by the
Realm
class as before, but passing the configuration as parameter.
If we want to see the outcome of this initialization, simply invoke the
InitializeRealm()
method in the constructor of the
MainWindow.xaml.cs
file, like in the following example:
public MainWindow()
{
InitializeComponent();
InitializeRealm();
}
If the app is running as a native desktop app, you will find the database created in the following path:
C:\Users\<username>\AppData\Local\RealmDesktop\
Since we’re leveraging the AppData folder, when the app will run as converted through the Desktop Bridge, Windows will take care for us of performing the proper file system redirection. To see it in action,
just follow the guidance of one the previous posts on this blog
: add a new WinJS project to the solution and make sure to edit the .csproj file of the WPF project to add an
AfterBuild
task that will take care of copying the output of the WPF build inside a subfolder of the WinJS project, which we’ll use to create our packages, launch it as a converted app, etc. I won’t explain the details of all the steps you need to follow, since they are detailed in the
previous blog post
.
At the end, this is how your solution should look like:
And here comes the second caveat to keep in mind when it comes to implement Realm in a converted desktop app. If you explore the
bin/Debug
folder of the standard desktop application, you will see that it has the following structure:
As you can see, other than the standard executable and DLL libraries that have been copied also inside our WinJS project, we have also
a
lib
folder, which contains a file called
realm-wrappers.dll
. However, you will find two versions of it: one compiled for x86 and one for x64. The reason is that, under the hood, the Realm Mobile Database is implemented using C++ and, as such, the core library can’t be cross-compiled for both architectures, but you need to have a specific version based on the architecture for which the converted version of the app is compiled. As such, let’s say that we want to create a converted version compiled for the x86 architecture: we’ll need to enter into the
lib/x86
folder, copy the
realm-wrappers.dll
file and paste it inside the
win32
folder of our WinJS project. This requirement, instead, doesn’t apply when the app is launched as native: the reason is that the Realm NuGet package installs a component that takes care of copying the proper version of the DLL, based on the architecture for which the native desktop app is being compiled. In case of a converted app, this component doesn’t work, so we need to manually take care of copying the right DLL. This is what we did in the previous example: we took the
real-wrappers.dll
file inside the
lib/x86
folder and we copied it in the
win32
folder of the WinJS project. Eventually, if you have the requirement to produce different packages for different architectures, you can leverage a post-build task: one for the configuration when the native desktop app is compiled for the x86 architecture, which copies the 32 bit version of the library, and one for the configuration when the app is compiled for the x64 architecture, which copies the 64 bit version of the library.
Now try to launch the converted version of the app, by setting the WinJS project as startup, as configuration the
x86
architecture and by choosing, from the Visual Studio menu,
Debug –> Start without debugging
(remember that the WinJS project facilitates our job in launching the converted version, creating the app packages, etc., but it can’t be used for real debugging). This time, since the app will run as converted, you’ll be able to see the Desktop Bridge file system redirection at work: the new database file will be placed in the local folder of the app, under the
c:\Users\<username>\AppData\Local\Packages
folder. In my case, for example, I was able to find the
default.realm
file in the path
From a Desktop Bridge point of view, that’s all you need to know to understand how to leverage Realm Mobile Database in a converted desktop app:
If you want to keep the install / uninstall experience clean and efficient, remember to change the default path where the database is created, so that it can be deleted when the app is uninstalled (unless, of course, the ability of keeping the database across multiple installs / uninstall is one of your requirements).
Remember to manually copy the
realm-wrappers.dll
file from the
lib/x86
or
lib/x64
folder, which is placed inside the
bin
folder of the desktop project, inside the
win32
folder of the WinJS folder, based on the architecture for which you want to compile and distribute your application. Of course, this choice affects also the procedure of creating the AppX using the option
Store –> Create app packages
that you can find when you right click on the WinJS project. If, for example, you have chosen to use the x86 version of the
realm-wrappers.dll
library, you will have to create an AppX which contains just the x86 version of the app.
Working with Realm
Again, the purpose of this post is to share with you how to properly use Realm inside a desktop app converted with the Desktop Bridge, so I won’t go into all the details and opportunities that you can leverage working with the Realm database. However, at the same time, I don’t want you to “tease you” to learn how to configure Realm, without showing at least how to leverage it to perform some basic operations.
As such, let’s start by defining a simple user interface in the
MainWindow.xaml
page, that will allow us to handle a collection of customers:
As you can see, the user interface is very simple:
A couple of
TextBox
control, to allow the user to specify the name and the surname of the customer
.
A button to add the customer to the database.
A button to retrieve the list of existing customers, so that we can display them in the
ListView
control placed at the bottom.
A button to update one of the fields of one of the existing customers.
This is how the interface looks like:
Now let’s see how to implement each feature. The first thing we need, as for every other scenario where we deal with data, is a model that represents the entities we need to work with. In this case, we’re working with customers, so we’re going to create a class called
Person
to store his name and surname:
public class Person: RealmObject
{
public string Name { get; set; }
public string Surname { get; set; }
}
You can immediately notice a peculiar feature, which is requested in order for Realm to map a table for this class: it has to inherit from the
RealmObject
class. There’s also another advantage in using it as a base class for our entity, but we’ll see it later.
Now that we have an entity, we can start adding instances of it inside the Realm database. To achieve this goal, the
Realm
instance we have retrieved at startup (thanks to the
InitializeRealm()
method) offers a method called
Write()
, which can be used to start a transaction: either the operation will succeed and the data will be successfully saved or the operation will fail and the database will be rollback prior to the change. Inside the
Write()
statement, we can define with an anonymous method the operation we want to perform. In this case, we want to add a new instance of a
Person
object, created by leveraging the data inserted by the user in the two
TextBox
controls:
private void OnSaveUser(object sender, RoutedEventArgs e)
{
realm.Write(() =>
{
Person person = new Person
{
Name = txtName.Text,
Surname = txtSurname.Text
};
To achieve this goal, it’s enough to call the
Add()
method on the
Realm
object, by passing as parameter the
Person
object we have just created. Now try to repeat the same operation and to add more customers, so that we have more data to work with. Now let’s try a basic reading operation: let’s retrieve all the elements and count how many items we have added.
private void OnGetCount(object sender, RoutedEventArgs e)
{
var list = realm.All<Person>();
MessageBox.Show($"Number of customers: {list.Count()}");
}
To access to the items stored in a table we can use the
All<T>()
method, passing as
T
the type of object we want to retrieve (in this case,
Person
). One of the benefits of Realm (which helps to achieve good writing / reading performances) is that when when we call the
All<T>()
method we have just retrieved a reference to the list, but we haven’t actually executed any query. The type of the result returned by the
All<T>()
method, in fact, is
IQueryable<T>.
The real operation on the database is performed only when we move on and we define the kind of query we want to perform: in this sample, the query is effectively executed when we call the
Count()
method, so that we can display to the user the number of customers inserted using a
MessageBox
.
We can use the same approach to display the list of customers using the
ListView
control we have placed in the XAML:
private void OnListCustomers(object sender, RoutedEventArgs e)
{
var result = realm.All<Person>().ToList();
listCustomers.ItemsSource = result;
}
The only difference is that, in this case, instead of the
Count()
method, we use the
ToList()
one, to perform the query and get the list of customers stored in the table. If you have some experience with XAML / C# development and binding, the rest of the code shouldn’t be complex to understand: we have set the list of customers as
ItemsSource
of the
ListView
control. Then, since in the
ListView
control we have defined an
ItemTemplate
to display the
Name
and
Surname
property of each
Person
object, the final result will be that the list in the XAML will be populated with list of customers we have previously added.
Last but not the least, we can use the
IQueryable<T>
result also to perform more complex queries:
As with Entity Framework or LINQ to SQL, all the queries are performed using LINQ statements: in this case, we’re using the
FirstOrDefault()
statement to retrieve the first customer of the collection which
surname is equal to
Pagani
. The sample code shows also two additional Realm features:
The
Write()
method can be used to perform any kind of operation with the database, not just adding, but also deleting or updating. In this case, we’re changing the
value of the
Name
property of the customer we have just retrieved and storing the update in the database.
After pressing the button, you would have noticed that, if you have previously inserted a customer with surname
Pagani
, his name would have been immediately changed in the user interface with the new one,
Giulia
. Do you remember that I told you that there was another advantage in using the
RealmObject
class as a base one for the
Person
entity? Well, you have just found it: out of the box, the
RealmObject
class will make your object’s properties implement the
INotifyPropertyChanged
interface, which is the key feature to dispatch changes in the objects defined in code to the controls that are in binding with them. This is the reason why, without any extra effort from you, the
ListView
will automatically update his visual layout to display the new name of the customer: every time we change the property of one of the items in our list, the object will send a notification to the UI, so the control will automatically update itself.
Wrapping up
In this post we have learned two new concepts at the same time: the first one is a new emerging technology, called Realm Database, which is becoming widely adopted by developers who has the requirement of store complex data in a permanent way in their applications. This technology was already available for many mobile platforms, like iOS or Android, but since a few weeks it supports also the .NET world, allowing us to leverage it also in Windows applications or in cross-platform applications developed with Xamarin. The second concept we have learned is how to leverage this new technology inside a desktop application converted with the Desktop Bridge, so that we can keep a clean deployment process and eventually
publish it on the Store
.
In this project the Realm NuGet package has been added directly in the WPF application, but remember that also Portable Class Libraries are supported: this means that your data layer (so the definition of the entities and the classes that performs the various operations on the database) can be included in a separate library and shared with a mobile app for Android or iOS developed with Xamarin. Additionally, the Realm team has confirmed that also support for the Universal Windows Platform is coming soon, so you’ll be able to leverage this new technology not only with traditional desktop or converted app, but also with new Windows 10 apps.
Happy coding!
Updated Nov 22, 2022
Version 5.0
No CommentsBe the first to comment
"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCoverImage\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeTitle\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTimeToRead\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505310105"}],"cachedText({\"lastModified\":\"1745505310105\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505310105"}]},"CachedAsset:pages-1745487429248":{"__typename":"CachedAsset","id":"pages-1745487429248","value":[{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730142000000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745487429248,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","entityType":"CATEGORY","displayId":"microsoft365","nodeType":"category","depth":3,"title":"Microsoft 365","shortTitle":"Microsoft 365","parent":{"__ref":"Category:category:products-services"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","entityType":"CATEGORY","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","entityType":"CATEGORY","shortTitle":"Products"},"Blog:board:ModernWorkAppConsult":{"__typename":"Blog","id":"board:ModernWorkAppConsult","entityType":"BLOG","displayId":"ModernWorkAppConsult","nodeType":"board","depth":4,"conversationStyle":"BLOG","title":"Modern Work App Consult Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:microsoft365"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:microsoft365"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"shortTitle":"Modern Work App Consult Blog","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"PRESET_ONLY"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":6,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:44595":{"__typename":"User","id":"user:44595","uid":44595,"login":"Matteo Pagani","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS00NDU5NS02MzA4OGkwNTU0MkU2NzQwODM2NTE0"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":117,"biography":null,"topicsCount":39,"kudosReceivedCount":132,"kudosGivenCount":1,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2017-03-19T04:38:14.936-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":1},"BlogTopicMessage:message:316667":{"__typename":"BlogTopicMessage","uid":316667,"subject":"Using Realm Mobile Database in a converted desktop app with the Desktop Bridge","id":"message:316667","revisionNum":5,"repliesCount":0,"author":{"__ref":"User:user:44595"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"conversation":{"__ref":"Conversation:conversation:316667"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:316667"},"teaser":"First published on MSDN on Feb 28, 2017 Realm Mobile Database is an open source project that has quickly become very popular, especially among mobile developers.","body":"\n \n \n First published on MSDN on Feb 28, 2017\n \n \n
\n \n Realm Mobile Database\n \n is an open source project that has quickly become very popular, especially among mobile developers. It’s an alternative to SQLite and it’s a way to store complex data in a permanent way, pretty much like you would do with a regular database. Some of the advantages of this technology are that:\n
\n \n
\n Like SQLite, it doesn’t need a “man in the middle” service (DBMS) to talk with the database (like SQL Server, Oracle, MySQL, etc.), but the application has direct access to it, making it a perfect match for mobile and simple applications.\n
\n
\n It’s based on an object oriented model so, similarly in a way you do when you work with technologies like Entity Framework, you don’t have to write manual SQL queries to perform operations but you can keep working with classes, objects and powerful manipulation languages like LINQ.\n
\n
\n It’s cross-platform, so you can share your database with the vast majority of platforms on the market.\n
\n
\n It supports UI notifications out of the box, so the user interface of your application can be automatically updated every time the data in the database changes.\n
\n \n
\n Why I’m talking about this technology in the AppConsult blog? Because the developer team behind Realm has recently announced support for .NET and Portable Class Libraries, which means that now you can use a Realm database also in Xamarin and Windows desktop applications. Can you see the direction where my post is going? As you’ll probably know if you have followed all the posts so far about the Desktop Bridge, there are some requirements that a converted desktop app must respect since:\n
\n \n
\n A converted app needs to always run in user mode, you can’t require the user to have administrative rights in order to use the app or parts of it.\n
\n
\n The deployment of a converted app is a “one click” procedure: you press an Install button (like when you use the Store), you wait for the package to be downloaded and installed and then you launch it.\n
\n \n
\n As such, some scenarios that would require a more complex configuration environment (like installing a SQL Server instance to handle a database) aren’t supported. When we’re talking about the Desktop Bridge, technologies like SQLite or Realm Mobile Database are just perfect: the database is stored in a single file and it’s directly accessed by the application, so we can simply deploy it in any folder of the computer and let the application read and write from it, without having to install any particular service.\n
\n
\n \n There’s a lot of documentation on the official website\n \n that covers how to use Realm in a .NET application, including all the advanced (like encryption and synchronization) and corner case scenarios. In this post I would like to focus on the basic usage of the Realm Mobile Database and how you can leverage it in a desktop app converted using the Desktop Bridge, since there are some important caveats to consider.\n
\n
\n For the purpose of this post, we’re going to create a simple WPF app that will allow us to:\n
\n \n
\n Create a new database to store a list of customers.\n
\n
\n Add some customers to the database.\n
\n
\n Retrieve the list of customers stored in the database.\n
\n
\n Update the info about one of the customers stored in the database.\n
\n \n
\n Let’s start!\n
\n
\n
\n
\n Configure Realm Mobile Database for the Desktop Bridge\n
\n
\n Let’s start by opening Visual Studio and by creating a new WPF project, which you can find by following the path\n \n File –> New project –> Templates –> Visual C# –> Windows Classic Desktop –> WPF App (.NET Framework)\n \n . Make sure to choose at least .NET 4.6.1, since it’s the minimum version supported by the Desktop Bridge. Adding support to Realm Mobile Database is easy, since the team has released it as a NuGet package: right click on the WPF project, choose\n \n Manage NuGet Packages\n \n and look for and install the package identified by the\n \n Realm\n \n name.\n
\n
\n \n
\n
\n By default, using Realm is quite easy: you can use the\n \n Realm\n \n class (included in the\n \n Realms\n \n namespace) and call the static method\n \n GetInstance()\n \n to get a reference to the database, which you will need later to perform all the standard CRUD operations (adding / removing / updating / reading an item). As such, the initialization code could be as easy as the following one:\n
\n However, when it comes to an app converted with the Desktop Bridge, this approach may have a downside. If you’ll try to execute it, you will notice that, by default, the database will be created in the\n \n Documents\n \n folder of the user. You will find, in fact, three new elements in this library:\n
\n \n \n \n
\n The main database, which is a file called\n \n default.realm\n \n .\n
\n \n
\n A lock file, used to handle concurrent operations, which is a file called\n \n default.realm.lock.\n \n
\n \n
\n A folder used to manage the database, called\n \n default.realm.management\n \n .\n
\n \n \n
\n This scenario is absolutely supported also by a converted desktop app: since it’s executed with the\n \n runFullTrust\n \n permission, it has the chance to read and write folders in the\n \n Documents\n \n folder of the user without problems (since it’s a folder which doesn’t require admin rights to be accessed). So, why I’m saying that using the default approach can be a downside? One of the benefits of the Desktop Bridge compared to a traditional desktop app is that it offers a cleaner deployment experience, in terms of install / uninstall / upgrade operations. As such, storing the database of the application in the\n \n Documents\n \n library isn’t a great idea, because it’s the kind of user generated content that doesn’t make sense without the application that has created it: a regular user won’t know what to do with a\n \n default.realm\n \n file after he has uninstalled your application. Wouldn’t be better to leverage the AppData folder provided by Windows for this scenario? Additionally, thanks to the file system redirection provided by the Desktop Bridge, storing the database in the AppData folder would mean that, when the user will decide to uninstall your app, also the database will be removed, without leaving unnecessary files on the user’s disk.\n
\n \n
\n We can achieve this goal thanks to a class called\n \n RealmConfiguration\n \n , that we can pass as parameter of the\n \n GetInstance()\n \n method and that we can use to customize the configuration of the database. One of the configurable parameters is exactly the path of the database. Here is a complete sample initialization code:\n
\n We’re using the standard .NET APIs to get access to the local AppData folder of the user (thanks to the enumerator\n \n Environment.SpecialFolder.LocalApplicationData\n \n , which represents the %LOCALAPPDATA% system variable). Inside this special folder, we create sub folder with the name of our application (in this case,\n \n RealmDesktop\n \n ), where we’re going to store the database. The first part of the code is pretty straightforward: if the app is running for the first time, the\n \n RealmDesktop\n \n folder doesn’t exist yet, so we need to create it first. Then we combine the path of the folder with the name of the database (in our case, we keep the standard name\n \n default.realm\n \n ) and we pass it as initialization parameter of a new\n \n RealmConfiguration\n \n object. Then we can leverage the same\n \n GetInstance()\n \n method offered by the\n \n Realm\n \n class as before, but passing the configuration as parameter.\n
\n \n
\n If we want to see the outcome of this initialization, simply invoke the\n \n InitializeRealm()\n \n method in the constructor of the\n \n MainWindow.xaml.cs\n \n file, like in the following example:\n
\n Since we’re leveraging the AppData folder, when the app will run as converted through the Desktop Bridge, Windows will take care for us of performing the proper file system redirection. To see it in action,\n \n just follow the guidance of one the previous posts on this blog\n \n : add a new WinJS project to the solution and make sure to edit the .csproj file of the WPF project to add an\n \n AfterBuild\n \n task that will take care of copying the output of the WPF build inside a subfolder of the WinJS project, which we’ll use to create our packages, launch it as a converted app, etc. I won’t explain the details of all the steps you need to follow, since they are detailed in the\n \n previous blog post\n \n .\n
\n \n
\n At the end, this is how your solution should look like:\n
\n \n
\n \n
\n \n
\n And here comes the second caveat to keep in mind when it comes to implement Realm in a converted desktop app. If you explore the\n \n bin/Debug\n \n folder of the standard desktop application, you will see that it has the following structure:\n
\n \n
\n \n
\n \n
\n As you can see, other than the standard executable and DLL libraries that have been copied also inside our WinJS project, we have also\n \n \n a\n \n lib\n \n folder, which contains a file called\n \n realm-wrappers.dll\n \n . However, you will find two versions of it: one compiled for x86 and one for x64. The reason is that, under the hood, the Realm Mobile Database is implemented using C++ and, as such, the core library can’t be cross-compiled for both architectures, but you need to have a specific version based on the architecture for which the converted version of the app is compiled. As such, let’s say that we want to create a converted version compiled for the x86 architecture: we’ll need to enter into the\n \n lib/x86\n \n folder, copy the\n \n realm-wrappers.dll\n \n file and paste it inside the\n \n win32\n \n folder of our WinJS project. This requirement, instead, doesn’t apply when the app is launched as native: the reason is that the Realm NuGet package installs a component that takes care of copying the proper version of the DLL, based on the architecture for which the native desktop app is being compiled. In case of a converted app, this component doesn’t work, so we need to manually take care of copying the right DLL. This is what we did in the previous example: we took the\n \n real-wrappers.dll\n \n file inside the\n \n lib/x86\n \n folder and we copied it in the\n \n win32\n \n folder of the WinJS project. Eventually, if you have the requirement to produce different packages for different architectures, you can leverage a post-build task: one for the configuration when the native desktop app is compiled for the x86 architecture, which copies the 32 bit version of the library, and one for the configuration when the app is compiled for the x64 architecture, which copies the 64 bit version of the library.\n
\n \n
\n Now try to launch the converted version of the app, by setting the WinJS project as startup, as configuration the\n \n x86\n \n architecture and by choosing, from the Visual Studio menu,\n \n Debug –> Start without debugging\n \n (remember that the WinJS project facilitates our job in launching the converted version, creating the app packages, etc., but it can’t be used for real debugging). This time, since the app will run as converted, you’ll be able to see the Desktop Bridge file system redirection at work: the new database file will be placed in the local folder of the app, under the\n \n c:\\Users\\<username>\\AppData\\Local\\Packages\n \n folder. In my case, for example, I was able to find the\n \n default.realm\n \n file in the path\n
\n From a Desktop Bridge point of view, that’s all you need to know to understand how to leverage Realm Mobile Database in a converted desktop app:\n
\n \n \n \n
\n If you want to keep the install / uninstall experience clean and efficient, remember to change the default path where the database is created, so that it can be deleted when the app is uninstalled (unless, of course, the ability of keeping the database across multiple installs / uninstall is one of your requirements).\n
\n \n
\n Remember to manually copy the\n \n realm-wrappers.dll\n \n file from the\n \n lib/x86\n \n or\n \n lib/x64\n \n folder, which is placed inside the\n \n bin\n \n folder of the desktop project, inside the\n \n win32\n \n folder of the WinJS folder, based on the architecture for which you want to compile and distribute your application. Of course, this choice affects also the procedure of creating the AppX using the option\n \n Store –> Create app packages\n \n that you can find when you right click on the WinJS project. If, for example, you have chosen to use the x86 version of the\n \n realm-wrappers.dll\n \n library, you will have to create an AppX which contains just the x86 version of the app.\n
\n \n \n
\n Working with Realm\n
\n \n
\n Again, the purpose of this post is to share with you how to properly use Realm inside a desktop app converted with the Desktop Bridge, so I won’t go into all the details and opportunities that you can leverage working with the Realm database. However, at the same time, I don’t want you to “tease you” to learn how to configure Realm, without showing at least how to leverage it to perform some basic operations.\n
\n \n
\n As such, let’s start by defining a simple user interface in the\n \n MainWindow.xaml\n \n page, that will allow us to handle a collection of customers:\n
\n As you can see, the user interface is very simple:\n
\n \n \n \n
\n A couple of\n \n TextBox\n \n control, to allow the user to specify the name and the surname of the customer\n \n .\n \n
\n \n
\n A button to add the customer to the database.\n
\n \n
\n A button to retrieve the list of existing customers, so that we can display them in the\n \n ListView\n \n control placed at the bottom.\n
\n \n
\n A button to update one of the fields of one of the existing customers.\n
\n \n \n
\n This is how the interface looks like:\n
\n \n
\n \n
\n \n
\n Now let’s see how to implement each feature. The first thing we need, as for every other scenario where we deal with data, is a model that represents the entities we need to work with. In this case, we’re working with customers, so we’re going to create a class called\n \n Person\n \n to store his name and surname:\n
\n public class Person: RealmObject\n \n {\n \n public string Name { get; set; }\n \n public string Surname { get; set; }\n \n }\n \n \n
\n You can immediately notice a peculiar feature, which is requested in order for Realm to map a table for this class: it has to inherit from the\n \n RealmObject\n \n class. There’s also another advantage in using it as a base class for our entity, but we’ll see it later.\n
\n \n
\n Now that we have an entity, we can start adding instances of it inside the Realm database. To achieve this goal, the\n \n Realm\n \n instance we have retrieved at startup (thanks to the\n \n InitializeRealm()\n \n method) offers a method called\n \n Write()\n \n , which can be used to start a transaction: either the operation will succeed and the data will be successfully saved or the operation will fail and the database will be rollback prior to the change. Inside the\n \n Write()\n \n statement, we can define with an anonymous method the operation we want to perform. In this case, we want to add a new instance of a\n \n Person\n \n object, created by leveraging the data inserted by the user in the two\n \n TextBox\n \n controls:\n
\n To achieve this goal, it’s enough to call the\n \n Add()\n \n method on the\n \n Realm\n \n object, by passing as parameter the\n \n Person\n \n object we have just created. Now try to repeat the same operation and to add more customers, so that we have more data to work with. Now let’s try a basic reading operation: let’s retrieve all the elements and count how many items we have added.\n
\n private void OnGetCount(object sender, RoutedEventArgs e)\n \n {\n \n var list = realm.All<Person>();\n \n MessageBox.Show($\"Number of customers: {list.Count()}\");\n \n }\n \n \n
\n To access to the items stored in a table we can use the\n \n All<T>()\n \n method, passing as\n \n T\n \n the type of object we want to retrieve (in this case,\n \n Person\n \n ). One of the benefits of Realm (which helps to achieve good writing / reading performances) is that when when we call the\n \n All<T>()\n \n method we have just retrieved a reference to the list, but we haven’t actually executed any query. The type of the result returned by the\n \n All<T>()\n \n method, in fact, is\n \n IQueryable<T>.\n \n The real operation on the database is performed only when we move on and we define the kind of query we want to perform: in this sample, the query is effectively executed when we call the\n \n Count()\n \n method, so that we can display to the user the number of customers inserted using a\n \n MessageBox\n \n .\n
\n \n
\n We can use the same approach to display the list of customers using the\n \n ListView\n \n control we have placed in the XAML:\n
\n The only difference is that, in this case, instead of the\n \n Count()\n \n method, we use the\n \n ToList()\n \n one, to perform the query and get the list of customers stored in the table. If you have some experience with XAML / C# development and binding, the rest of the code shouldn’t be complex to understand: we have set the list of customers as\n \n ItemsSource\n \n of the\n \n ListView\n \n control. Then, since in the\n \n ListView\n \n control we have defined an\n \n ItemTemplate\n \n to display the\n \n Name\n \n and\n \n Surname\n \n property of each\n \n Person\n \n object, the final result will be that the list in the XAML will be populated with list of customers we have previously added.\n
\n \n
\n Last but not the least, we can use the\n \n IQueryable<T>\n \n result also to perform more complex queries:\n
\n As with Entity Framework or LINQ to SQL, all the queries are performed using LINQ statements: in this case, we’re using the\n \n FirstOrDefault()\n \n statement to retrieve the first customer of the collection which\n \n \n surname is equal to\n \n Pagani\n \n . The sample code shows also two additional Realm features:\n
\n \n \n \n
\n The\n \n Write()\n \n method can be used to perform any kind of operation with the database, not just adding, but also deleting or updating. In this case, we’re changing the\n \n \n value of the\n \n Name\n \n property of the customer we have just retrieved and storing the update in the database.\n
\n \n
\n After pressing the button, you would have noticed that, if you have previously inserted a customer with surname\n \n Pagani\n \n , his name would have been immediately changed in the user interface with the new one,\n \n Giulia\n \n . Do you remember that I told you that there was another advantage in using the\n \n RealmObject\n \n class as a base one for the\n \n Person\n \n entity? Well, you have just found it: out of the box, the\n \n RealmObject\n \n class will make your object’s properties implement the\n \n INotifyPropertyChanged\n \n interface, which is the key feature to dispatch changes in the objects defined in code to the controls that are in binding with them. This is the reason why, without any extra effort from you, the\n \n ListView\n \n will automatically update his visual layout to display the new name of the customer: every time we change the property of one of the items in our list, the object will send a notification to the UI, so the control will automatically update itself.\n
\n \n \n
\n
\n \n
\n
\n \n
\n Wrapping up\n
\n \n
\n In this post we have learned two new concepts at the same time: the first one is a new emerging technology, called Realm Database, which is becoming widely adopted by developers who has the requirement of store complex data in a permanent way in their applications. This technology was already available for many mobile platforms, like iOS or Android, but since a few weeks it supports also the .NET world, allowing us to leverage it also in Windows applications or in cross-platform applications developed with Xamarin. The second concept we have learned is how to leverage this new technology inside a desktop application converted with the Desktop Bridge, so that we can keep a clean deployment process and eventually\n \n publish it on the Store\n \n .\n
\n In this project the Realm NuGet package has been added directly in the WPF application, but remember that also Portable Class Libraries are supported: this means that your data layer (so the definition of the entities and the classes that performs the various operations on the database) can be included in a separate library and shared with a mobile app for Android or iOS developed with Xamarin. Additionally, the Realm team has confirmed that also support for the Universal Windows Platform is coming soon, so you’ll be able to leverage this new technology not only with traditional desktop or converted app, but also with new Windows 10 apps.\n
\n \n
\n Happy coding!\n
\n \n","body@stringLength":"31266","rawBody":"\n \n \n First published on MSDN on Feb 28, 2017\n \n \n
\n \n Realm Mobile Database\n \n is an open source project that has quickly become very popular, especially among mobile developers. It’s an alternative to SQLite and it’s a way to store complex data in a permanent way, pretty much like you would do with a regular database. Some of the advantages of this technology are that:\n
\n \n
\n Like SQLite, it doesn’t need a “man in the middle” service (DBMS) to talk with the database (like SQL Server, Oracle, MySQL, etc.), but the application has direct access to it, making it a perfect match for mobile and simple applications.\n
\n
\n It’s based on an object oriented model so, similarly in a way you do when you work with technologies like Entity Framework, you don’t have to write manual SQL queries to perform operations but you can keep working with classes, objects and powerful manipulation languages like LINQ.\n
\n
\n It’s cross-platform, so you can share your database with the vast majority of platforms on the market.\n
\n
\n It supports UI notifications out of the box, so the user interface of your application can be automatically updated every time the data in the database changes.\n
\n \n
\n Why I’m talking about this technology in the AppConsult blog? Because the developer team behind Realm has recently announced support for .NET and Portable Class Libraries, which means that now you can use a Realm database also in Xamarin and Windows desktop applications. Can you see the direction where my post is going? As you’ll probably know if you have followed all the posts so far about the Desktop Bridge, there are some requirements that a converted desktop app must respect since:\n
\n \n
\n A converted app needs to always run in user mode, you can’t require the user to have administrative rights in order to use the app or parts of it.\n
\n
\n The deployment of a converted app is a “one click” procedure: you press an Install button (like when you use the Store), you wait for the package to be downloaded and installed and then you launch it.\n
\n \n
\n As such, some scenarios that would require a more complex configuration environment (like installing a SQL Server instance to handle a database) aren’t supported. When we’re talking about the Desktop Bridge, technologies like SQLite or Realm Mobile Database are just perfect: the database is stored in a single file and it’s directly accessed by the application, so we can simply deploy it in any folder of the computer and let the application read and write from it, without having to install any particular service.\n
\n
\n \n There’s a lot of documentation on the official website\n \n that covers how to use Realm in a .NET application, including all the advanced (like encryption and synchronization) and corner case scenarios. In this post I would like to focus on the basic usage of the Realm Mobile Database and how you can leverage it in a desktop app converted using the Desktop Bridge, since there are some important caveats to consider.\n
\n
\n For the purpose of this post, we’re going to create a simple WPF app that will allow us to:\n
\n \n
\n Create a new database to store a list of customers.\n
\n
\n Add some customers to the database.\n
\n
\n Retrieve the list of customers stored in the database.\n
\n
\n Update the info about one of the customers stored in the database.\n
\n \n
\n Let’s start!\n
\n
\n
\n
\n Configure Realm Mobile Database for the Desktop Bridge\n
\n
\n Let’s start by opening Visual Studio and by creating a new WPF project, which you can find by following the path\n \n File –> New project –> Templates –> Visual C# –> Windows Classic Desktop –> WPF App (.NET Framework)\n \n . Make sure to choose at least .NET 4.6.1, since it’s the minimum version supported by the Desktop Bridge. Adding support to Realm Mobile Database is easy, since the team has released it as a NuGet package: right click on the WPF project, choose\n \n Manage NuGet Packages\n \n and look for and install the package identified by the\n \n Realm\n \n name.\n
\n
\n \n
\n
\n By default, using Realm is quite easy: you can use the\n \n Realm\n \n class (included in the\n \n Realms\n \n namespace) and call the static method\n \n GetInstance()\n \n to get a reference to the database, which you will need later to perform all the standard CRUD operations (adding / removing / updating / reading an item). As such, the initialization code could be as easy as the following one:\n
\n However, when it comes to an app converted with the Desktop Bridge, this approach may have a downside. If you’ll try to execute it, you will notice that, by default, the database will be created in the\n \n Documents\n \n folder of the user. You will find, in fact, three new elements in this library:\n
\n \n \n \n
\n The main database, which is a file called\n \n default.realm\n \n .\n
\n \n
\n A lock file, used to handle concurrent operations, which is a file called\n \n default.realm.lock.\n \n
\n \n
\n A folder used to manage the database, called\n \n default.realm.management\n \n .\n
\n \n \n
\n This scenario is absolutely supported also by a converted desktop app: since it’s executed with the\n \n runFullTrust\n \n permission, it has the chance to read and write folders in the\n \n Documents\n \n folder of the user without problems (since it’s a folder which doesn’t require admin rights to be accessed). So, why I’m saying that using the default approach can be a downside? One of the benefits of the Desktop Bridge compared to a traditional desktop app is that it offers a cleaner deployment experience, in terms of install / uninstall / upgrade operations. As such, storing the database of the application in the\n \n Documents\n \n library isn’t a great idea, because it’s the kind of user generated content that doesn’t make sense without the application that has created it: a regular user won’t know what to do with a\n \n default.realm\n \n file after he has uninstalled your application. Wouldn’t be better to leverage the AppData folder provided by Windows for this scenario? Additionally, thanks to the file system redirection provided by the Desktop Bridge, storing the database in the AppData folder would mean that, when the user will decide to uninstall your app, also the database will be removed, without leaving unnecessary files on the user’s disk.\n
\n \n
\n We can achieve this goal thanks to a class called\n \n RealmConfiguration\n \n , that we can pass as parameter of the\n \n GetInstance()\n \n method and that we can use to customize the configuration of the database. One of the configurable parameters is exactly the path of the database. Here is a complete sample initialization code:\n
\n We’re using the standard .NET APIs to get access to the local AppData folder of the user (thanks to the enumerator\n \n Environment.SpecialFolder.LocalApplicationData\n \n , which represents the %LOCALAPPDATA% system variable). Inside this special folder, we create sub folder with the name of our application (in this case,\n \n RealmDesktop\n \n ), where we’re going to store the database. The first part of the code is pretty straightforward: if the app is running for the first time, the\n \n RealmDesktop\n \n folder doesn’t exist yet, so we need to create it first. Then we combine the path of the folder with the name of the database (in our case, we keep the standard name\n \n default.realm\n \n ) and we pass it as initialization parameter of a new\n \n RealmConfiguration\n \n object. Then we can leverage the same\n \n GetInstance()\n \n method offered by the\n \n Realm\n \n class as before, but passing the configuration as parameter.\n
\n \n
\n If we want to see the outcome of this initialization, simply invoke the\n \n InitializeRealm()\n \n method in the constructor of the\n \n MainWindow.xaml.cs\n \n file, like in the following example:\n
\n Since we’re leveraging the AppData folder, when the app will run as converted through the Desktop Bridge, Windows will take care for us of performing the proper file system redirection. To see it in action,\n \n just follow the guidance of one the previous posts on this blog\n \n : add a new WinJS project to the solution and make sure to edit the .csproj file of the WPF project to add an\n \n AfterBuild\n \n task that will take care of copying the output of the WPF build inside a subfolder of the WinJS project, which we’ll use to create our packages, launch it as a converted app, etc. I won’t explain the details of all the steps you need to follow, since they are detailed in the\n \n previous blog post\n \n .\n
\n \n
\n At the end, this is how your solution should look like:\n
\n \n
\n \n
\n \n
\n And here comes the second caveat to keep in mind when it comes to implement Realm in a converted desktop app. If you explore the\n \n bin/Debug\n \n folder of the standard desktop application, you will see that it has the following structure:\n
\n \n
\n \n
\n \n
\n As you can see, other than the standard executable and DLL libraries that have been copied also inside our WinJS project, we have also\n \n \n a\n \n lib\n \n folder, which contains a file called\n \n realm-wrappers.dll\n \n . However, you will find two versions of it: one compiled for x86 and one for x64. The reason is that, under the hood, the Realm Mobile Database is implemented using C++ and, as such, the core library can’t be cross-compiled for both architectures, but you need to have a specific version based on the architecture for which the converted version of the app is compiled. As such, let’s say that we want to create a converted version compiled for the x86 architecture: we’ll need to enter into the\n \n lib/x86\n \n folder, copy the\n \n realm-wrappers.dll\n \n file and paste it inside the\n \n win32\n \n folder of our WinJS project. This requirement, instead, doesn’t apply when the app is launched as native: the reason is that the Realm NuGet package installs a component that takes care of copying the proper version of the DLL, based on the architecture for which the native desktop app is being compiled. In case of a converted app, this component doesn’t work, so we need to manually take care of copying the right DLL. This is what we did in the previous example: we took the\n \n real-wrappers.dll\n \n file inside the\n \n lib/x86\n \n folder and we copied it in the\n \n win32\n \n folder of the WinJS project. Eventually, if you have the requirement to produce different packages for different architectures, you can leverage a post-build task: one for the configuration when the native desktop app is compiled for the x86 architecture, which copies the 32 bit version of the library, and one for the configuration when the app is compiled for the x64 architecture, which copies the 64 bit version of the library.\n
\n \n
\n Now try to launch the converted version of the app, by setting the WinJS project as startup, as configuration the\n \n x86\n \n architecture and by choosing, from the Visual Studio menu,\n \n Debug –> Start without debugging\n \n (remember that the WinJS project facilitates our job in launching the converted version, creating the app packages, etc., but it can’t be used for real debugging). This time, since the app will run as converted, you’ll be able to see the Desktop Bridge file system redirection at work: the new database file will be placed in the local folder of the app, under the\n \n c:\\Users\\<username>\\AppData\\Local\\Packages\n \n folder. In my case, for example, I was able to find the\n \n default.realm\n \n file in the path\n
\n From a Desktop Bridge point of view, that’s all you need to know to understand how to leverage Realm Mobile Database in a converted desktop app:\n
\n \n \n \n
\n If you want to keep the install / uninstall experience clean and efficient, remember to change the default path where the database is created, so that it can be deleted when the app is uninstalled (unless, of course, the ability of keeping the database across multiple installs / uninstall is one of your requirements).\n
\n \n
\n Remember to manually copy the\n \n realm-wrappers.dll\n \n file from the\n \n lib/x86\n \n or\n \n lib/x64\n \n folder, which is placed inside the\n \n bin\n \n folder of the desktop project, inside the\n \n win32\n \n folder of the WinJS folder, based on the architecture for which you want to compile and distribute your application. Of course, this choice affects also the procedure of creating the AppX using the option\n \n Store –> Create app packages\n \n that you can find when you right click on the WinJS project. If, for example, you have chosen to use the x86 version of the\n \n realm-wrappers.dll\n \n library, you will have to create an AppX which contains just the x86 version of the app.\n
\n \n \n
\n Working with Realm\n
\n \n
\n Again, the purpose of this post is to share with you how to properly use Realm inside a desktop app converted with the Desktop Bridge, so I won’t go into all the details and opportunities that you can leverage working with the Realm database. However, at the same time, I don’t want you to “tease you” to learn how to configure Realm, without showing at least how to leverage it to perform some basic operations.\n
\n \n
\n As such, let’s start by defining a simple user interface in the\n \n MainWindow.xaml\n \n page, that will allow us to handle a collection of customers:\n
\n As you can see, the user interface is very simple:\n
\n \n \n \n
\n A couple of\n \n TextBox\n \n control, to allow the user to specify the name and the surname of the customer\n \n .\n \n
\n \n
\n A button to add the customer to the database.\n
\n \n
\n A button to retrieve the list of existing customers, so that we can display them in the\n \n ListView\n \n control placed at the bottom.\n
\n \n
\n A button to update one of the fields of one of the existing customers.\n
\n \n \n
\n This is how the interface looks like:\n
\n \n
\n \n
\n \n
\n Now let’s see how to implement each feature. The first thing we need, as for every other scenario where we deal with data, is a model that represents the entities we need to work with. In this case, we’re working with customers, so we’re going to create a class called\n \n Person\n \n to store his name and surname:\n
\n public class Person: RealmObject\n \n {\n \n public string Name { get; set; }\n \n public string Surname { get; set; }\n \n }\n \n \n
\n You can immediately notice a peculiar feature, which is requested in order for Realm to map a table for this class: it has to inherit from the\n \n RealmObject\n \n class. There’s also another advantage in using it as a base class for our entity, but we’ll see it later.\n
\n \n
\n Now that we have an entity, we can start adding instances of it inside the Realm database. To achieve this goal, the\n \n Realm\n \n instance we have retrieved at startup (thanks to the\n \n InitializeRealm()\n \n method) offers a method called\n \n Write()\n \n , which can be used to start a transaction: either the operation will succeed and the data will be successfully saved or the operation will fail and the database will be rollback prior to the change. Inside the\n \n Write()\n \n statement, we can define with an anonymous method the operation we want to perform. In this case, we want to add a new instance of a\n \n Person\n \n object, created by leveraging the data inserted by the user in the two\n \n TextBox\n \n controls:\n
\n To achieve this goal, it’s enough to call the\n \n Add()\n \n method on the\n \n Realm\n \n object, by passing as parameter the\n \n Person\n \n object we have just created. Now try to repeat the same operation and to add more customers, so that we have more data to work with. Now let’s try a basic reading operation: let’s retrieve all the elements and count how many items we have added.\n
\n private void OnGetCount(object sender, RoutedEventArgs e)\n \n {\n \n var list = realm.All<Person>();\n \n MessageBox.Show($\"Number of customers: {list.Count()}\");\n \n }\n \n \n
\n To access to the items stored in a table we can use the\n \n All<T>()\n \n method, passing as\n \n T\n \n the type of object we want to retrieve (in this case,\n \n Person\n \n ). One of the benefits of Realm (which helps to achieve good writing / reading performances) is that when when we call the\n \n All<T>()\n \n method we have just retrieved a reference to the list, but we haven’t actually executed any query. The type of the result returned by the\n \n All<T>()\n \n method, in fact, is\n \n IQueryable<T>.\n \n The real operation on the database is performed only when we move on and we define the kind of query we want to perform: in this sample, the query is effectively executed when we call the\n \n Count()\n \n method, so that we can display to the user the number of customers inserted using a\n \n MessageBox\n \n .\n
\n \n
\n We can use the same approach to display the list of customers using the\n \n ListView\n \n control we have placed in the XAML:\n
\n The only difference is that, in this case, instead of the\n \n Count()\n \n method, we use the\n \n ToList()\n \n one, to perform the query and get the list of customers stored in the table. If you have some experience with XAML / C# development and binding, the rest of the code shouldn’t be complex to understand: we have set the list of customers as\n \n ItemsSource\n \n of the\n \n ListView\n \n control. Then, since in the\n \n ListView\n \n control we have defined an\n \n ItemTemplate\n \n to display the\n \n Name\n \n and\n \n Surname\n \n property of each\n \n Person\n \n object, the final result will be that the list in the XAML will be populated with list of customers we have previously added.\n
\n \n
\n Last but not the least, we can use the\n \n IQueryable<T>\n \n result also to perform more complex queries:\n
\n As with Entity Framework or LINQ to SQL, all the queries are performed using LINQ statements: in this case, we’re using the\n \n FirstOrDefault()\n \n statement to retrieve the first customer of the collection which\n \n \n surname is equal to\n \n Pagani\n \n . The sample code shows also two additional Realm features:\n
\n \n \n \n
\n The\n \n Write()\n \n method can be used to perform any kind of operation with the database, not just adding, but also deleting or updating. In this case, we’re changing the\n \n \n value of the\n \n Name\n \n property of the customer we have just retrieved and storing the update in the database.\n
\n \n
\n After pressing the button, you would have noticed that, if you have previously inserted a customer with surname\n \n Pagani\n \n , his name would have been immediately changed in the user interface with the new one,\n \n Giulia\n \n . Do you remember that I told you that there was another advantage in using the\n \n RealmObject\n \n class as a base one for the\n \n Person\n \n entity? Well, you have just found it: out of the box, the\n \n RealmObject\n \n class will make your object’s properties implement the\n \n INotifyPropertyChanged\n \n interface, which is the key feature to dispatch changes in the objects defined in code to the controls that are in binding with them. This is the reason why, without any extra effort from you, the\n \n ListView\n \n will automatically update his visual layout to display the new name of the customer: every time we change the property of one of the items in our list, the object will send a notification to the UI, so the control will automatically update itself.\n
\n \n \n
\n
\n \n
\n
\n \n
\n Wrapping up\n
\n \n
\n In this post we have learned two new concepts at the same time: the first one is a new emerging technology, called Realm Database, which is becoming widely adopted by developers who has the requirement of store complex data in a permanent way in their applications. This technology was already available for many mobile platforms, like iOS or Android, but since a few weeks it supports also the .NET world, allowing us to leverage it also in Windows applications or in cross-platform applications developed with Xamarin. The second concept we have learned is how to leverage this new technology inside a desktop application converted with the Desktop Bridge, so that we can keep a clean deployment process and eventually\n \n publish it on the Store\n \n .\n
\n In this project the Realm NuGet package has been added directly in the WPF application, but remember that also Portable Class Libraries are supported: this means that your data layer (so the definition of the entities and the classes that performs the various operations on the database) can be included in a separate library and shared with a mobile app for Android or iOS developed with Xamarin. Additionally, the Realm team has confirmed that also support for the Universal Windows Platform is coming soon, so you’ll be able to leverage this new technology not only with traditional desktop or converted app, but also with new Windows 10 apps.\n
\n \n
\n Happy coding!\n
\n \n","kudosSumWeight":0,"postTime":"2019-01-15T14:04:04.494-08:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MTlpQ0M1MjU2MzQ5NjQwRkU5Qg?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjBpNzcyQ0UyN0IzQkYwOEY1QQ?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjFpNjREOTlCQzk1NTE1MjJEQQ?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjNpQjY3MUM1N0M2RjI0RDQwMA?revision=5\"}"}}],"totalCount":4,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:Desktop Bridge","text":"Desktop Bridge","time":"2019-01-15T13:53:06.792-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:Universal Windows Platform","text":"Universal Windows Platform","time":"2017-08-22T12:18:41.301-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":15,"rawTeaser":"First published on MSDN on Feb 28, 2017 Realm Mobile Database is an open source project that has quickly become very popular, especially among mobile developers.","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:316667_5"},"latestVersion":{"__typename":"FriendlyVersion","major":"5","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":2867},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":5}},"Conversation:conversation:316667":{"__typename":"Conversation","id":"conversation:316667","solved":false,"topic":{"__ref":"BlogTopicMessage:message:316667"},"lastPostingActivityTime":"2022-11-22T12:24:17.731-08:00","lastPostTime":"2019-01-15T14:04:04.494-08:00","unreadReplyCount":0,"isSubscribed":false},"ModerationData:moderation_data:316667":{"__typename":"ModerationData","id":"moderation_data:316667","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MTlpQ0M1MjU2MzQ5NjQwRkU5Qg?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MTlpQ0M1MjU2MzQ5NjQwRkU5Qg?revision=5","title":"","associationType":"BODY","width":640,"height":60,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjBpNzcyQ0UyN0IzQkYwOEY1QQ?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjBpNzcyQ0UyN0IzQkYwOEY1QQ?revision=5","title":"","associationType":"BODY","width":272,"height":450,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjFpNjREOTlCQzk1NTE1MjJEQQ?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjFpNjREOTlCQzk1NTE1MjJEQQ?revision=5","title":"","associationType":"BODY","width":460,"height":213,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjNpQjY3MUM1N0M2RjI0RDQwMA?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTY2NjctNjY4MjNpQjY3MUM1N0M2RjI0RDQwMA?revision=5","title":"","associationType":"BODY","width":252,"height":361,"altText":null},"Revision:revision:316667_5":{"__typename":"Revision","id":"revision:316667_5","lastEditTime":"2022-11-22T12:24:17.731-08:00"},"CachedAsset:theme:customTheme1-1744326567485":{"__typename":"CachedAsset","id":"theme:customTheme1-1744326567485","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505310105","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505310105","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1745502713103":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1745502713103","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1745505310105","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1745505311091":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1745505311091","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505310105","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-1744400828020":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-1744400828020","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size: 14px;\n }\n}\n","texts":null,"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1x9u2_1 {\n a.custom_widget_community_banner_top-bar_1x9u2_2.custom_widget_community_banner_btn_1x9u2_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size: 0.875rem;\n }\n}\n","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1x9u2_1","top-bar":"custom_widget_community_banner_top-bar_1x9u2_2","btn":"custom_widget_community_banner_btn_1x9u2_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-1744400828020":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-1744400828020","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-1744400828020":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-1744400828020","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505310105","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1745505310105","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:316667:5":{"__typename":"QueryVariables","id":"TopicReplyList:message:316667:5","value":{"id":"message:316667","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505310105","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505310105","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505310105","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505310105","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505310105","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505310105","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1745505310105","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1745505310105","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1745505310105","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505310105","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505310105","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1745505310105","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1745505310105","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1745505310105","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505310105","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505310105","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1745505310105","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505310105","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1745505310105","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1745505310105","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1745505310105","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1745505310105","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1745505310105","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505310105","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1745505310105","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1745505310105","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1745505310105","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1745505310105","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1745505310105","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505310105":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505310105","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"modernworkappconsult","messageSubject":"using-realm-mobile-database-in-a-converted-desktop-app-with-the-desktop-bridge","messageId":"316667"},"buildId":"HEhyUrv5OXNBIbfCLaOrw","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.1.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/external/components/ExternalComponent.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Amodernworkappconsult&entity.id=message%3A316667","strategy":"afterInteractive"}]}