Sitelets in C#
See the main documentation of sitelets in F# here.
However, there are also API dedicated for ease of use in C#. For example, there are Task
-based versions of the F# Async
-based methods.
Below is the C# equivalent of the minimal example:
Routing
You can create endpoint types as classes.
The main difference from F# is that you need to specify the order of the fields of the class that are used to generate/parse the URL segments in your [EndPoint]
attribute.
SiteletBuilder
A handy way to create a sitelet is by using the SiteletBuilder
class. It functions conceptually similar to StringBuilder
, you can chain methods to assemble a final value:
- First, create an instance of
SiteletBuilder()
; - Then, add your mappings using
.With<T>(...)
method calls; - Finally, use
.Install()
to return your constructedSitelet
.
This creates a Sitelet<object>
, which means it has less type safety than the F# version, but it is more flexible in C#.
For example, using the endpoint types defined in the above section, you can create the following Sitelet:
The above sitelets accepts URLs with the following shape:
It is also possible to create an endpoint for a specific URL, without associating an endpoint type to it:
Defining endpoints
The following types can be used as endpoints:
- Numbers and strings are encoded as a single path segment.
- Arrays are encoded as a number representing the length, followed by each element.
System.Tuple
s,ValueTuple
s and objects are encoded with their fields as consecutive path segments.
- Objects with an
[EndPoint]
attribute are prefixed with the given path segment.
- Enumerations are encoded as their underlying type.
System.DateTime
is serialized with the formatyyyy-MM-dd-HH.mm.ss
by default. Use[DateTimeFormat(string)]
on a field to customize it. Be careful as some characters are not valid in URLs; in particular, the ISO 8601 round-trip format ("o"
format) cannot be used because it uses the character:
.
- The attribute
[Method("GET", "POST", ...)]
on a class indicates which methods are accepted by this endpoint. Without this attribute, all methods are accepted.
- If an endpoint accepts only one method, then a more concise way to specify it is directly in the
[EndPoint]
attribute:
- A common trick is to use
[EndPoint("GET /")]
on a field-less class to indicate the home page.
- If several classes have the same
[EndPoint]
, then parsing tries them in the order in which they are passed to.With()
until one of them matches:
[Query]
on a field indicates that this field must be parsed as a GET query parameter instead of a path segment. The value of this field must be either a base type (number, string) or anNullable
of a base type (in which case the parameter is optional).
- You can of course mix Query and non-Query parameters.
-
[Json]
on a field indicates that it must be parsed as JSON from the body of the request. If an endpoint type contains several[Json]
fields, a runtime error is thrown.
[Wildcard]
on a field indicates that it represents the remainder of the url's path. That field can be aT[]
or astring
. If an endpoint type contains several[Wildcard]
fields, a runtime error is thrown.
Other Constructors and Combinators
Many of the same combinators are available in C# as in F#. See the F# documentation. The main differences are:
Sitelet.Sum
andSitelet.Folder
haveparams
arguments, so you can pass multiple sitelets as an array or as a comma-separated list.- Methods that modify a single sitelet are available as extension methods on
Sitelet<T>
, while those that combine multiple sitelets are available as static methods in theSitelet
class. These are.Box
,.Protect
,.Map
, and.Shift
. For example, mapping a sitelet works like this:
Content
Similar content-creating functions are available in C# as in F#. See the F# documentation.
The main difference is that the content functions return a Task<Content>
instead of Async<Content>
.
For example, the following code creates a simple HTML page:
Using the Context
The method SiteletBuilder.With()
provides a context of type Context
. This is similar to the web context object available in F#, but it is not generic in C#.
Creating links
Here is an example using context.Link
from C# to create links from endpoint objects:
Note how context.Link
is used in order to resolve the URL to the Article
endpoint.
context.ResolveUrl
helps to manually construct application-relative URLs to resources that do not map to sitelet endpoints.
Managing User Sessions
The Context
object can also be used to access the currently logged in user. The member UserSession
has the following Task
-based extension members, which require using WebSharper.Web;
:
-
Task LoginUserAsync(string username, bool persistent = false)
Task LoginUserAsync(string username, System.TimeSpan duration)
Logs in the user with the given username. This sets a cookie that is uniquely associated with this username. The second parameter determines the expiration of the login:
-
LoginUserAsync("username")
creates a cookie that expires with the user's browser session. -
LoginUserAsync("username", persistent: true)
creates a cookie that lasts indefinitely. -
LoginUserAsync("username", duration: d)
creates a cookie that expires after the given duration.
Example:
-
-
Task<string> GetLoggedInUserAsync()
Retrieves the currently logged in user's username, or
null
if the user is not logged in.Example:
-
Task LogoutAsync()
Logs the user out.
Example:
The implementation of these functions relies on cookies and thus requires that the browser has enabled cookies.