Search code examples
c#jsonjson.netexpandoobject

How can I declare a dynamic property name starting with an @


I need to create the following JSON:

 {
      "@context": "https://schema.org",
      "@type": "Event",
      "name": "The Adventures of Kira and Morrison",
      "startDate": "2025-07-21T19:00-05:00",
      "endDate": "2025-07-21T23:00-05:00",

So I wrote the following C#

private MarkupString JsonLdEvent
{
    get
    {
        dynamic data = new
        {
            @context = "https://schema.org",
            @type = "Event",
            name = Data?.Subject,
            startDate = Data?.UnderlyingEvent?.StartDateTime.DateTimeOffset,
            endDate = Data?.UnderlyingEvent?.EndDateTime.DateTimeOffset,
        };

        var json = JsonConvert.SerializeObject(data, Formatting.Indented);
        return new MarkupString(json);
    }
}

The problem is the generated JSON has "context": "https://schema.org" not "@context": "https://schema.org". Is there a way to set the property to @context?

Update: If you hit this exact issue - need to create Schema.Org objects - there's a .NET library that provides this (@David's solution).


Solution

  • When @context is used as an identifier, the @ just means "this isn't a keyword" - i.e. so you can have a member called new, unsafe, int, or similiar - obj.@int means "the member called int on obj", where int is otherwise a reserved keyword. So: that's why it isn't working.

    If you actually need dynamic members (i.e. the structure isn't fixed), then maybe instead:

    var dict = new Dictionary<string, object>();
    dict["@context"] = "https://schema.org";
    // ...
    

    Or as @daremachine says in the comments: [JsonProperty] / [JsonPropertyName] on a regular POCO.