App
Quick Reference for all APIs
This is a quick CheatSheet to provide you with a reference to most APIs you'll use.
This uses a base class of @inherits Custom.Hybrid.RazorTyped
. Most samples would not work on older Razor base classes such as @inherits Custom.Hybrid.Razor14
as that provides different objects and methods.
Selected: Typed (2sxc 16+) Switch to Dynamic (Razor14 or below)
- Show firstName (string): Terry
-
Show birthday (DateTime):
4/28/1948 12:00:00 AM -
Show birthday (DateTime, formatted):
1948-04-28 - Show age (int): 76
- Show decades (int): 7
- Show decadesFloat (float): 7.6
- Show decadesInt (int): 7
- Basic set variable and show
Create variables and show using
@variableName
⬇️ Result | Source ➡️
Show old/not old based on Terry's age using
@if
and @else
:
this guy is old
Ternare show old/not old based on age ? ... :
:
this guy is old
- Razor Conditions such as if, if-else and ? :
if/else and ternary operator
(condition ? true : false)
⬇️ Result | Source ➡️
Loop through Pets using
@foreach (var thing in list)
- dog
- cat
- mouse
Loop through Pets using
@for (counter; condition; increment)
- dog - owned by Daniel
- cat - owned by John
- mouse - owned by Markus
- Loops -
for
andforeach
Loops using
for()
andforeach()
⬇️ Result | Source ➡️
Output values (HTML-source shown)
- this is text, it doesn't have tags
- this string <em>has</em> html <strong>tags</strong>
Output values (HTML is used; maybe security risk)
- this is text, it doesn't have tags
- this string has html tags
- Work with HTML Output
Learn the difference of showing variables with
@variable
and@Html.Raw(variable)
, and re-use very simple snippets
⬇️ Result | Source ➡️
You can just use any Emoji in your source. Or you pick them with ternary operations.
- This is just an emoji: 🚀
- Pick emoji from true ⇒ ✔️
- Pick emoji from true ⇒ ❌
- Working with 😃 Emojis / Emoticons
Show Emojis in your output or use them for showing true/false
A common task is to link to a specific page or to stay on the same page but with different URL parameters.
⬇️ Result | Source ➡️
Normally you would use the following in an href
attribute.
Current Page
- This page URL:
https://oqt-apps-dev.2sxc.org/razortutorial12
- This page url params:
authorId=46286&id=46295&tut=quickref
- Link this page without params:
https://oqt-apps-dev.2sxc.org/razortutorial12
- Link this page with same params:
https://oqt-apps-dev.2sxc.org/razortutorial12?authorId=46286&id=46295&tut=quickref
- Link this page with same params:
https://oqt-apps-dev.2sxc.org/razortutorial12?authorId=46286&id=46295&tut=quickref
- Link this page with more params:
https://oqt-apps-dev.2sxc.org/razortutorial12?authorId=46286&id=46295&tut=quickref&another&more=27&more=42
- Link this page remove params:
https://oqt-apps-dev.2sxc.org/razortutorial12?authorId=46286&id=46295&tut=quickref
- Link this page replace params:
https://oqt-apps-dev.2sxc.org/razortutorial12?authorId=46286&id=46295&tut=quickref&quick-ref-typed=test
Another Page
This only works if you don't have a page 12, otherwise you'll see an error in the url.
- Link to page 12 without params:
https://oqt-apps-dev.2sxc.org/admin/profiles
- Link to page 12 with current params:
https://oqt-apps-dev.2sxc.org/admin/profiles?authorId=46286&id=46295&tut=quickref
Reuse Razor and CSharp Files
Don't-Repeat-Yourself (DRY) by reusing code in Razor and helper C# files.
⬇️ Result | Source ➡️
Reuse some functions inside this file
- Boolmoji(true) ⇒ 👍🏽
- Boolmoji(false) ⇒ 👎🏽
- Random number function: 83
- Random number function: 73
- this is a bold item in a list using a Template Delegate
- another bold item in a list using a Template Delegate
- Code - Function and Similar Helpers
Normal C# functions are the basic block for reusing code.
- Reuse Shared Razor Helpers (CreateInstance / GetCode)
Use a shared razor file to hold multiple functions / helpers, and call them one-by-one as needed.
- Reuse Code and Razor Templates
Explains the basics of re-using code across templates and code files.
⬇️ Result | Source ➡️
Call some external Razor files
- Reuse Shared Templates with Html.Partial and MyModel
Reuse Razor files by calling them using
@Html.Partial
and passing parameters in DynamicModel (or MyModel).
⬇️ Result | Source ➡️
Call some external Razor files
-
Hello, this is the first line
-
Second line!
-
Third line!
- Reuse Shared Templates with Html.Partial and MyModel
Reuse Razor files by calling them using
@Html.Partial
and passing parameters in DynamicModel (or MyModel).
Reuse Partial Razor and functions from Helper Code files.
⬇️ Result | Source ➡️
Call some Code in External CSharp Files
- Hello from shared lib: Hello!
-
QR Code from shared lib
- Reuse Shared Razor Helpers (CreateInstance / GetCode)
Use a shared razor file to hold multiple functions / helpers, and call them one-by-one as needed.
Razor doesn't know about types inside code files, so you need some tricks to work with objects which are passed around.
⬇️ Result | Source ➡️
Working with anonymous objects
The only way to get values from an anonymous object
created elsewhere is using
AsTyped(... as object)
.
Everything else will 🚫.
- Anon: { Name = John, Age = 30 }
- Anon Type: <>f__AnonymousType0`2[System.String,System.Int32]
- aTyped.Name ✅: John
- Anon.Name 🚫: ⚠️ Exception: 'object' does not contain a definition for 'Name'
- anonDyn.Name 🚫: ⚠️ Exception: 'object' does not contain a definition for 'Name'
- aTypedDyn.Name 🚫: ⚠️ Exception: 'ToSic.Sxc.Data.Internal.Typed.WrapObjectTyped' does not contain a definition for 'Get'
Working with ITyped
objects
If the returned object is based on ITyped
, things are a bit easier.
But you must still ensure that Razor knows the type.
- Name ✅: John
- Name (string) ✅: John
Working with real objects
If the returned object is based on a class, things are a bit easier.
- Person: ReturnObjects+Person
- Person Type: ReturnObjects+Person
- Person.Name ✅: John
- pTyped.Get("Name") ✅: John
- pTyped.String("Name") ✅: John
- pTypedDyn.Get("Name") 🚫: ⚠️ Exception: 'ToSic.Sxc.Data.Internal.Typed.WrapObjectTyped' does not contain a definition for 'Get'
Working with dictionaries
If the returned object is based on a dictionary, things are a bit easier.
This is because dynamic
will be able to work with it, but it's not type safe.
- dicDyn: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dicDyn Type: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dicDyn Count ✅: 2
- dicDyn["Name"] ✅: John
- dic: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dic Type: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dic Count ✅: 2
- dic["Name"] ✅: John
- Reuse Shared Razor Helpers (CreateInstance / GetCode)
Use a shared razor file to hold multiple functions / helpers, and call them one-by-one as needed.
Work with Content Items - MyItem
MyItem is the object which contains the first thing added by the editor on the current block.
Every view/template receives prepared data, usually on the MyItem
object.
⬇️ Result | Source ➡️
Douglas Adams on MyItem
Id, Guid and Title are built-in properties
- Id: 46284
- Guid: 36726e4e-21cd-4c00-9ce8-72080f8935da
- Title: Douglas
Use Get(…)
if you don't care about the var type...
- Name: Douglas
- Birthday: 3/11/1952 12:00:00 AM
... or Get<T>(…)
which will try to treat as the expected type.
- Birthday Get<string> 03/11/1952 00:00:00
- Birthday Get<DateTime> 3/11/1952 12:00:00 AM
- Birthday Get<bool> False
- Birthday Get<int> 0
Use typed methods such as .String(…)
if you care about the variable type.
- Name (strings): Douglas Adams
- Birthday: 3/11/1952
- Is Alive: False
- Fav Num. Int: 42
- Fav Num. Float: 41.99
Use fallback: …
to handle empty values or conversion problems.
- Name (strings): Douglas
- Name (int): 12345
Use .Attribute(…)
to safely encode properties.
Mouse over this to see the effect.
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
- Working with Entity (Item) Values
Every thing is an Entity. Here some basic examples how to show values like Name, Birthday etc. of such an Entity.
- Working with Block Contents
Show content which was entered for this module
⬇️ Result | Source ➡️
Douglas Adams on MyItem
Note: The Biography contains a LOT of HTML...
Teaser (using .Raw() for Umlauts):
Douglas Noël Adams (11 March 1952 – 11 May 2001) was an English author, humorist , and…
(drag size to see responsiv behavior)
Douglas Noël Adams (11 March 1952 – 11 May 2001) was an English author, humorist, and screenwriter, best known for The Hitchhiker's Guide to the Galaxy. Originally a 1978 BBC radio comedy, The Hitchhiker's Guide to the Galaxy developed into a "trilogy" of five books that sold more than 15 million copies in his lifetime.
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
The Presentation property only exists if the view is configured to use Presentation. In which case this is used to specify additional information how something should look or be presented.
⬇️ Result | Source ➡️
A Person on MyItem
Note that the following should be green (probably green)
Content number 1
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: QuickRefContent
- Content/Item IsList: True
- Content/Item Data:
- Content number 1 (ID: 46806) - Presentation: green (ID: 46802)
- Content two (ID: 46807) - Presentation: red (ID: 46809)
- Content three (ID: 46811) - Presentation: cyan (ID: 46810)
- Working with Entity (Item) Values
Every thing is an Entity. Here some basic examples how to show values like Name, Birthday etc. of such an Entity.
- Working with Block Contents
Show content which was entered for this module
Child items such as Awards
are accessed using Child("Awards")
. There are many ways to work with them.
⬇️ Result | Source ➡️
Use .Child("Awards")
to get one
- Award ID: 46329
- Award Name: Hugo Award
- Award Name (Path): Hugo Award
Use ContainsKey(…), IsEmpty(…), IsNotEmpty(…)
- ContainsKey("Awards"): True
- ContainsKey("Awards2"): False
- IsEmpty("Awards"): False
- IsNotEmpty("Awards"): True
- IsEmpty("Awards.Name"): False
- IsEmpty("Awards2.Name"): True
- IsEmpty("Awards.NameX"): True
Use .Children("Awards")
to get all
Award Count: 2
- Award: Hugo Award
- Award: Inkpot Award
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
- Working with Entity (Item) Values
Every thing is an Entity. Here some basic examples how to show values like Name, Birthday etc. of such an Entity.
- Working with Block Contents
Show content which was entered for this module
Properties can contain urls such as /abc.jpg
or file references like file:72
.
⬇️ Result | Source ➡️
Douglas Adams, the current item (MyItem)
Use .Url(…)
to resolve file references such as file:72
- Mugshot field Value: file:137
- Mugshot URL: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas%20adams.png
-
Mugshot Picture
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
Properties can contain urls such as /abc.jpg
or file references like file:72
.
⬇️ Result | Source ➡️
Douglas Adams, the current item (MyItem)
- File name: douglas adams
- File extension: png
- Size (bytes): 39125
- SizeInfo: 38.2 KB
Every file-field is actually a folder...
- Files count: 2
- Sub-Folders: 0
...which could hold many files.
If you want to show them, you need Kit.Image...
- douglas adams
- not-panicking
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
⬇️ Result | Source ➡️
Inspect the fields of an Item
- ✅ FavoriteNumber: 41.99
- ✅ Biography: <p><strong><img class="wysiwyg-right wysiwyg-50" src="/Portals/tutorial-razor/adam/Tutorial-Razor/Tm5yNs0hAEyc6HIID4k12g/Biography/douglas_adams_portrait.jpg" data-cmsid="file:douglas_adams_portrait.jpg">Douglas Noël Adams</strong> (11 March 1952 – 11 May 2001) was an English author, <a title="Humorist" href="https://en.wikipedia.org/wiki/Humorist" target="_blank" rel="noopener">humorist</a>, and screenwriter, best known for <i><a title="The Hitchhiker's Guide to the Galaxy" href="https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy" target="_blank" rel="noopener">The Hitchhiker's Guide to the Galaxy</a></i>. Originally a 1978 <a title="The Hitchhiker's Guide to the Galaxy (radio series)" href="https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy_(radio_series)" target="_blank" rel="noopener">BBC radio comedy</a>, <i>The Hitchhiker's Guide to the Galaxy</i> developed into a "trilogy" of five books that sold more than 15 million copies in his lifetime. <sup id="cite_ref-radioacad_2-0" class="reference"></sup></p>
- ✅ Birthday: 3/11/1952 12:00:00 AM
- ✅ FirstName: Douglas
- 🔲 Haters: System.Collections.Generic.List`1[ToSic.Sxc.Data.ITypedItem]
- ✅ IsAlive: False
- ✅ Mugshot: file:137
- ✅ LastName: Adams
- ✅ Awards: System.Collections.Generic.List`1[ToSic.Sxc.Data.ITypedItem]
- 🔲 Sex:
Let's do some manual inspection
- ✅ "FirstName" exits?
- 🔲 "FirstName" is empty?
- ✅ "FirstName" is not empty?
- 🔲 "hello" exits?
- ✅ "hello" is empty?
- 🔲 "hello" is not empty?
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
In some scenarios you need may expect that data isn't there. In that case, you can create fake items to use in your razor.
⬇️ Result | Source ➡️
Inspect the fields of an Item
- ✅ FirstName: John
- ✅ LastName: Doe
Every view/template receives prepared data, either entered by the user on this page, or provided through a query. It can contain many items - so to get the list, use MyItems
⬇️ Result | Source ➡️
Loop persons which were added to this view
- Douglas Adams
- Terry Pratchett
- Neil Gaiman
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item IsList: True
- Content/Item Data:
- Douglas (ID: 46284)
- Terry (ID: 46285)
- Neil (ID: 46286)
⬇️ Result | Source ➡️
-
Content number 1
FYI: Heading noneWe are one!
-
Content two
FYI: Heading h5Two be or !2B
-
Content three 🌟
FYI: Heading h6Three's the charm
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: QuickRefContent
- Content/Item IsList: True
- Content/Item Data:
- Content number 1 (ID: 46806) - Presentation: green (ID: 46802)
- Content two (ID: 46807) - Presentation: red (ID: 46809)
- Content three (ID: 46811) - Presentation: cyan (ID: 46810)
⬇️ Result | Source ➡️
Check out this list
- Content number 1
- Content two
- Content three
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: QuickRefContent
- Content/Item IsList: True
- Content/Item Data:
- Content number 1 (ID: 46806)
- Content two (ID: 46807)
- Content three (ID: 46811)
- Header Type: QuickRefContentHeader
- Header Item: Check out this list (ID: 46805)
Every view/template receives prepared data, either entered by the user on this page, or provided through a query.
⬇️ Result | Source ➡️
Loop persons in Query of this view
- Douglas Adams
- Terry Pratchett
- Neil Gaiman
This uses a query which returns a list of Persons and a selected person separately. The Default
stream has persons, and Selected
has a selected person to compare with. Compare using .Equals(…)
.
⬇️ Result | Source ➡️
- Douglas Adams
- Terry Pratchett (selected ⭐)
- Neil Gaiman
⬇️ Result | Source ➡️
Get Books from the Default
stream
- Hitchhikers Guide to the Galaxy
- Good Omens
- Phishing for Phools
- The Last Continent
Get Authors from the Authors
stream
- Douglas
- Terry
- Neil
- George
- Raphael
- Ed
⬇️ Result | Source ➡️
Get Books from the Default
stream
- Hitchhikers Guide to the Galaxy
- Good Omens
- Phishing for Phools
Get Authors from the Authors
stream
- Douglas
- Terry
- Neil
⬇️ Result | Source ➡️
Let's see the if anything exists
- ✅ Authors exists?
- 🔲 Critics exists?
- ✅ Players exists?
- ✅ Critics || Authors exists?
- ✅ Players || Authors exists?
Now let's count what's inside
- Authors: 6
- Critics: skip
- Players: 0
- Critics || Authors: 6
- Players || Authors: 0
Work with Settings and Resources
Settings can be configured at many levels, the most-local (eg. the App) would override the most global (eg. Presets).
⬇️ Result | Source ➡️
Get some App Setting / Resources
- Setting CustomColor:
#E91E63F2
- Setting CsvFile:
file:189
/razortutorial12/app/Tutorial-Razor/adam/FP6nrGBJZUKPRnldQOMQEQ/CsvFile/products.csv
- Resource ButtonOrder:
Get Global Settings
- Settings.Images.Content.Width
1400
- The same with prefix
Settings
1400
- GoogleMaps.DefaultCoordinates
{"latitude":47.1747,"longitude":9.4692}
- GoogleMaps.DefaultCoordinates as Typed
Lat: 47.1747
Lng: 9.4692
- Settings in 2sxc
Settings allow your code to use predefined settings across all apps and sites. And they allow you to overide a setting at any level of the application. You can read more about the settings in the docs 📕 .
Set Page Title, Keywords etc.
⬇️ Result | Source ➡️
Note: you won't see any output here. To see the effect, look at the page source.
Output is Invisible as it only affects the HTML Head
This sample modifies the HTML head, so it's not visible here.
To see the effect, look at the source in the browser
- Set Page Title, Keywords, Descriptions etc.
Get/Set Page Title, Keywords, Description and set meta-tags and more.
- Set <base> tag in header
Add a <base> tag to the header. This is important for SPA JS applications.
- Page Icons for Favicon, Apple/Android
Add various combinations of icons to the page header
- Meta and other Tags in header
Add all kinds of meta-tags to the header.
Set OpenGraph Headers etc.
⬇️ Result | Source ➡️
This uses Kit.Page.SetTitle(...)
and other methods to modify the HTML sent to the browser.
It sets various aspecs such as title
or FavIcons.
meta title
,meta description
,meta keywords
- favicon
- some JsonLd for google
- OpenGraph headers for FaceBook, Twitter, etc.
Output is Invisible as it only affects the HTML Head
This sample modifies the HTML head, so it's not visible here.
To see the effect, look at the source in the browser
- Set Open-Graph headers for Social Media using the IPageService
Add Open-Graph data headers for Facebook, Twitter and other sharing-systems
- JSON-LD Headers for SEO
Add JSON-LD (Linked Data) headers for Google
Get Info about Platform, Culture/Languages etc.
⬇️ Result | Source ➡️
- Platform name: '
Oqtane
' - Platform type: '
Oqtane
' - Platform version: '
5.0.2
' - Culture Current Code: '
en-us
' - Culture Default Code: '
en-us
' - Site Id: '
13
' - Site Url: '
https://oqt-apps-dev.2sxc.org/razortutorial12
' - Site UrlRoot: '
oqt-apps-dev.2sxc.org/razortutorial12
' - Page Id: '
288
' - Page Url: '
https://oqt-apps-dev.2sxc.org/razortutorial12
' - Page Url Parameters: '
authorId=46286&id=46295&tut=quickref
' - Module Id: '
352
' - User Id: '
-1
' - User Name: '
'
- User IsContentAdmin: '
False
' - User IsSiteAdmin: '
False
' - User IsSystemAdmin: '
False
' - View Id: '
47382
' - View Identifier: '
' (blank if no special identifier)
- View Name: '
Default Tutorial Page (new v16)
' - View Edition: '
' (blank if no special CSS Framework edition)
- Unique Key '
oUnaN94Z
'
- Work with the Context (Page, Site, etc.)
Whenever you need to know about the current environment, you need Context information. These are the contexts you should know about: Platform Site Page Module View User
Loading JavaScripts is standard HTML using <script src="..."<
tags. What more challenging is getting the right path to scripts in this app or relative to the current Razor file.
⬇️ Result | Source ➡️
Load a JavaScript relative to the App folder (see message/console):
Load a JavaScript relative to the folder of this Razor file (see message/console):
A core challenge is to activate JavaScripts only when needed - and when all dependencies are loaded. This is what turnOn
does. It checks if all specified JS objects exist, and then triggers the JS code.
⬇️ Result | Source ➡️
The following text will be replaced once the JS is triggered:
This example passes data to the JS, so it can be parameterized:
We can also pass in more sophisticated data:
Work with the new UniqueKey with JavaScript - new v16.04 🌟
The UniqueKey
is a new feature in 2sxc 16.04 which allows you to create unique IDs for HTML elements. The value of UniqueKey
is the same in all Razor and C# files for the same Content-Block.
⬇️ Result | Source ➡️
This separate Razor will create a div for the resulting message, based on the same UniqueKey
which is oUnaN94Z
(script didn't run yet - this elements id is demo-uniquekey-msg-oUnaN94Z
)
Sometimes you need a UniqueKey
which also depends on other objects. For example, you may need to have a UniqueKey which also uses another value - or many. This is done using @Kit.Key.UniqueKeyWith(...)
.
⬇️ Result | Source ➡️
-
Unique Key with
12345
:oUnaN94Z-n12345
-
Unique Key with
"hello"
:oUnaN94Z-s-1321432939
-
Unique Key with
"bad chars in id ! % / 👍🏽"
:oUnaN94Z-s-1566037177
-
Unique Key with
"this is a long text and should be shortened"
:oUnaN94Z-s1260891569
-
Unique Key with
12345
and"hello"
:oUnaN94Z-n12345-s-1321432939
If the UniqueKey
is based on known object types such as Entities, this works very well. For example, you may need to loop through a list of items, and each item needs a unique key.
⬇️ Result | Source ➡️
-
Title:
Hitchhikers Guide to the Galaxy
- UniqueKey:oUnaN94Z-eid7md5eRsH
-
Title:
Good Omens
- UniqueKey:oUnaN94Z-eidcAcM-LSz
-
Title:
Phishing for Phools
- UniqueKey:oUnaN94Z-eidlkSe34Oo
-
Title:
The Last Continent
- UniqueKey:oUnaN94Z-eid_EnbtOtU
JSON data can be difficult to work with, because you would need to use System.Text.Json
which has a sophisticated API. Instead, we can convert it to ITyped
and then use a very simple API.
⬇️ Result | Source ➡️
-
.Get("name")
: Dude -
.Get("NAME")
(insensitive): Dude
This example shows more advanced scenarios. It uses the previously created dude
object.
⬇️ Result | Source ➡️
-
.String("Name")
(typed): Dude -
.Int("Age")
: 47 -
Add using Int(...):
147
-
Add using String(...):
10047
By default, the object is strict, so you can only access fields which are present.
⬇️ Result | Source ➡️
-
strict.String("Fake")
(typed): ⚠️ Exception: String('Fake', ...) not found and 'strict' is true, meaning that an error is thrown. Either a) correct the name 'Fake'; b) use String("Fake", required: false); or c) or use AsItem(..., propsRequired: false) or similar (Parameter 'name') -
strict.String("Fake", required: false)
: -
strict.String("Fake", required: false, fallback: "undefined")
: undefined -
strict.Int("Fake", required: false)
: 0 -
strict.Int("Fake", required: false, fallback: -1)
: -1
By default, the object is strict, so you can only access fields which are present.
⬇️ Result | Source ➡️
-
loose.String("Fake")
(typed): -
loose.String("Fake")
: -
loose.String("Fake", fallback: "I don't know!")
: I don't know! -
loose.Int("Fake")
: 0 -
loose.Int("Fake", fallback: -1)
: -1
JSON data can be difficult to work with, because you would need to use System.Text.Json
which has a sophisticated API. Instead, we can convert it to ITyped
and then use a very simple API.
⬇️ Result | Source ➡️
Marc
- marc.ToString():
{ "name": "Marc", "age": 33, "car": null, "friends": [ { "name": "John", "age": 33 }, { "name": "Jane", "age": 33 } ] }
- name
.String("Name")
Marc
- age:
33
- birth year:
1991
- car make (will be null):
-
Friends using
AsTypedList(...)
- John
- Jane
Frank
- #2 frank.ToString():
{ "name": "Frank", "age": 44, "car": { "make": "Ford", "model": "Focus" } }
- #2 name:
Frank
- #2 car make:
Ford
- #2 car ToString():
{ "make": "Ford", "model": "Focus" }
⬇️ Result | Source ➡️
1
1
2
3
5
8
13
21
34
55
⬇️ Result | Source ➡️
-
Buchs
: 9470
Partner Cities: Oklohoma, New York -
Grabs
: 0 -
Sevelen
: 0
If you have an array in your Json, you need to use ToTypedList
.
⬇️ Result | Source ➡️
- Name:
Buchs
- Name:
Grabs
- Name:
Sevelen