C# Views - Use Name from ViewAttribute instead of Method Name
# Description of Changes
The [documentation for C#
views](https://spacetimedb.com/docs/modules/c-sharp#views) says that
"Views must be declared as Public, **with an explicit Name**, and
[...]". However, the `Name` provided to the `View` attribute is not
being used as the name of the view in the Module or the generated C#
client SDK code. The `ViewDeclaration` actually checks that the `View`
attribute's name is not null or empty, but then proceeds to do nothing
with it.
This PR updates the `ViewDeclaration` to use the `Name` property from
`ViewAttribute`.
For more info - see my bug report in Discord:
https://discord.com/channels/1037340874172014652/1443881580602069043
# API and ABI breaking changes
No breaking change to the API. Though, anyone who has a view name
declared that's different from their method name will have to deal with
that during migration of their modules.
# Expected complexity level and risk
1 - Trivial change
# Testing
I compiled the C# projects under `crates/bindings-csharp`, built the
NuGet packages, and tested them locally with a project using SpacetimeDB
1.10 (CLI and associated packages).
I confirmed that the generated classes now use the value from the `View`
attribute as the `RemoteTableName`. See attached image.
<img width="1429" height="372" alt="Screenshot 2025-11-28 at 3 04 48 PM"
src="https://github.com/user-attachments/assets/1db83c14-b0dc-4bcb-87ac-50e104f4d501"
/>
---------
Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
# Description of Changes
Implements the C# module bindings for Procedures (#3510)
# API and ABI breaking changes
None
# Expected complexity level and risk
2
# Testing
- [X] Locally tested against existing C# Procedures regression test
client (minus the Transaction and HTTP portions, as those are not in
this change).
# Description of Changes
1. Updates the Replication Tests in
`sdks/csharp/examples~/regression-tests` to include better coverage of
Views
2. Added missing linkage for __call_view__ and __call_view_anon__
3. Updated *ViewDispatcher Invoke to transform BSATN.ValueOption<> into
BSATN.List<>
4. Fixed issues with the indexing of views to match correctly during
__call_view__ and __call_view_anon__
# API and ABI breaking changes
No
# Expected complexity level and risk
2
# Testing
- [x] Running `run-regression-tests.sh` passes.
---------
Signed-off-by: rekhoff <r.ekhoff@clockworklabs.io>
Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
# Description of Changes
Closes: #3658
With the work on Views we ran into trouble with the Return Type and
certain C# code layout where the types are defined inside the Module
class. This fixes the bug in our current approach but needs
consideration to possibly be changed entirely.
# API and ABI breaking changes
N/A
# Expected complexity level and risk
1 - Minor change
# Testing
- [x] Retested with the linked code with and without the namespace
- [x] Re-ran regression tests
---------
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
# Description of Changes
Updates C# bindings to allow module authors to define `View`s and
`AnonymousView`s using the pattern:
```
[SpacetimeDB.View]
public static ExampleData? GetExampleDataById(ViewContext ctx, uint id)
{
return ctx.Db.ExampleData.Id.Find(id);
}
[SpacetimeDB.View]
public static ExampleData? GetAnonymousExampleDataById(AnonymousViewContext ctx, uint id)
{
return ctx.Db.ExampleData.Id.Find(id);
}
```
During publishing of a C# module, the views data will be converted into
`RawViewDefV9`
# API and ABI breaking changes
No known breaking changes
# Expected complexity level and risk
2
# Testing
- [X] Locally tested locally adding the above sample pattern to the
`sdks\csharp\examples~\regression-tests\server` test and performing a
`dotnet build` and a `spacetime publish test`, both of which succeeded.
---------
Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
# Description of Changes
The `aud` claim is required in the OIDC spec, but the server currently
allows it to be missing, and the spacetime auth tokens we use for the
website don't have an audience.
Previously the module bindings would throw an error if there were no
`aud` claim in a jwt payload (if someone used the `audience` within a
reducer), but this change makes us treat a missing audience as an empty
list.
This also renames the `authCtx` fields to `senderAuth` in the typescript
and csharp module APIs, so they match rust.
# API and ABI breaking changes
This doesn't break any ABIs.
This changes the ReducerContext APIs in typescript and rust, but only by
renaming a field that hasn't been released yet.
# Expected complexity level and risk
1.
# Testing
I've tested accessing the `audience` within a reducer for a token
missing an `aud` claim in Typescript and Rust.
# Description of Changes
This exposes JWT claims for csharp modules, similar to how they are
exposed to rust modules in
https://github.com/clockworklabs/SpacetimeDB/pull/3288.
This adds the new types `AuthCtx` and `JwtClaims`, and adds an `AuthCtx`
to the `ReducerContext`.
`AuthCtx` represents the credentials associated with the request, and
`JwtClaims` represents a jwt token.
One difference from the rust version is that I didn't create helpers to
build an `AuthCtx` from a jwt payload. The reason is that we would need
to be able to compute the identity from the payload claims, which
requires a blake3 hash implementation. The first two c# libraries I
found had issues at runtime
([Blake3](https://www.nuget.org/packages/Blake3) is wrapping a rust
implementation, and
[HashifyNet](https://github.com/Deskasoft/HashifyNET/tree/main/HashifyNet/Algorithms/Blake3)
seems to be broken by our trimming because it uses reflection heavily).
I can look into taking the implementation from `HashifyNet`, since it is
MIT licensed, but I don't think we need to block merging on that.
# API and ABI breaking changes
This adds the new types `AuthCtx` and `JwtClaims`, and adds an `AuthCtx`
to the `ReducerContext`.
This also adds a csharp wrapper for the get_jwt ABI function added in
https://github.com/clockworklabs/SpacetimeDB/pull/3288.
# Expected complexity level and risk
2.
# Testing
This has a very minimal unit test of JwtClaims.
I manually tested using this locally with the csharp quickstart, and I
was able to print jwt tokens inside the module.
# Description of Changes
This is the implementation of issue #3191. This adds a Default attribute
to C# module fields.
**Note**: In C#, attribute arguments must be compile-time constants,
which means you can't directly use non-constant expressions like new
expressions, method calls, or dynamic values in attribute constructors.
(Ref:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#2324-attribute-parameter-types)
For this reason, these default values are limited to primitive types,
enums, and strings.
This includes (shown as `C# Type` (`BSATN type`):
* `bool` (`Bool`)
* `sbyte` (`I8`)
* `byte` (`U8`)
* `short` (`I16`)
* `ushort` (`U16`)
* `int` (`I32`)
* `unit` (`U32`)
* `long` (`I64`)
* `ulong` (`U64`)
* `float` (`F32`)
* `double` (`F64`)
* `enum` (`Enum`)
* `string` (`String`)
* `null` (`RefOption`) <- Nullable type
Because of C# limitations, for nullable and complex data types, such as
a struct, can take use `[Default(null)]` to populate values with null
defaults. This allows things like structs to workaround the non-constant
expressions in attribute constructors limitation by allowing these
complex types to still be able to be added as new column tables.
The `int` type can also be in the form of Hex or Binary literals, such
as `[Default(0x2A)]` or `[Default(0b00101010)]`
Both Decimal (like `[Default(3.14m)]`) and Char (like `[Default('A')]`)
are unsupported types in BSATN and will still return `BSATN0001` errors.
# API and ABI breaking changes
Not API breaking.
This change only adds the `[Default(value)]` attribute logic.
Using the `[Default(value)]` attribute with older versions SpacetimeDB
C# modules will result in an error.
# Expected complexity level and risk
2
# Testing
Local testing of this requires use of CLI changes in #3278
- [x] Regression test of functionality added.
# Description of Changes
Fixes
https://github.com/orgs/clockworklabs/projects/22?pane=issue&itemId=102392974&issue=clockworklabs%7Ccom.clockworklabs.spacetimedbsdk%7C276
by renaming `internal` `static` serializer fields so that they do not
overlap with user-provided names.
Note, however, that some field names still will not work: `ReadFields`,
`WriteFields`, `Equals`, and `GetHashCode`.
This would require a separate fix since the error would happen in a
different place. In this case we would need to change the name of the
generated member to something like `ReadFields_` or `Equals_`, which I'm
not sure is a good idea.
# API and ABI breaking changes
N/A
# Expected complexity level and risk
0
# Testing
SDK tests and `dotnet-verify` tests are passing.
---------
Signed-off-by: rekhoff <r.ekhoff@clockworklabs.io>
Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>