---
title: 'C#'
description: "The JsonEvalRs NuGet package provides high-performance bindings for .NET applications. It wraps the Rust core engine with a user-friendly, type-safe C# API."
navigation:
  icon: 'i-simple-icons-csharp'
seo:
  title: 'C#'
  description: "The JsonEvalRs NuGet package provides high-performance bindings for .NET applications. It wraps the Rust core engine with a user-friendly, type-safe C# API."
---

## Installation

```bash
dotnet add package JsonEvalRs
```

Or via NuGet Package Manager:
```bash
Install-Package JsonEvalRs
```

## Quick Start

```csharp
using JsonEvalRs;
using Newtonsoft.Json.Linq;

// Define schema with validation rules and layout
string schema = @"{
    ""type"": ""object"",
    ""properties"": {
        ""email"": {
            ""type"": ""string"",
            ""rules"": {
                ""required"": { ""value"": true, ""message"": ""Email is required"" },
                ""pattern"": { 
                    ""value"": ""^[^@]+@[^@]+\\.[^@]+$"", 
                    ""message"": ""Invalid email format"" 
                }
            }
        }
    }
}";

// Use 'using' block for automatic disposal
using (var eval = new JSONEval(schema))
{
    // 1. Evaluate
    string data = @"{ ""email"": ""invalid-email"" }";
    eval.Evaluate(data);

    // 2. Validate
    ValidationResult validation = eval.Validate(data);
    
    if (validation.HasError)
    {
        foreach (var error in validation.Errors)
        {
            Console.WriteLine($"Field: {error.Path}, Error: {error.Message}");
        }
    }

    // 3. Get Evaluated Schema (includes computed properties)
    JObject result = eval.GetEvaluatedSchema();
}
```

## API Reference

### `JSONEval` Class

The main entry point for evaluation. Implements `IDisposable` to manage native resources.

#### Constructor

```csharp
public JSONEval(string schema, string? context = null, string? data = null)
```

-   **schema**: JSON schema definition string.
-   **context**: Optional external context data (e.g., user info, environment vars).
-   **data**: Optional initial data.

#### `Evaluate`

Evaluates the schema against provided data.

```csharp
public void Evaluate(string data, string? context = null, string[]? paths = null)
```

-   **data**: JSON data string.
-   **paths**: **[New]** Optional array of field paths for [Selective Evaluation](selective-evaluation).

#### `EvaluateOnly`

Evaluates the schema state internally without returning the computed JSON structure, providing a high-performance option when you don't need the final resolved document immediately.

```csharp
public void EvaluateOnly(string data, string? context = null, string[]? paths = null)
```

-   **data**: JSON data string.
-   **context**: Optional context data.
-   **paths**: Optional array of field paths.

#### `Validate`

Validates data against rules defined in the schema.

```csharp
public ValidationResult Validate(string data, string? context = null)
```

Returns `ValidationResult` containing:
-   `HasError` (bool)
-   `Errors` (List of `ValidationError`)

#### `EvaluateDependents`

Efficiently re-evaluates fields that depend on specific changes.

```csharp
public JArray EvaluateDependents(
    string[] changedPaths, 
    string? data = null, 
    string? context = null, 
    bool reEvaluate = false
)
```

-   **changedPaths**: List of paths that have changed (e.g., `["user.email"]`).
-   **reEvaluate**: If true, triggers a full `Evaluate` call after determining dependencies.

#### Advanced Methods

**`ValidatePaths`**
Validates only specific field paths within the data rather than the entire schema.
```csharp
public ValidationResult ValidatePaths(string data, string? context = null, List<string>? paths = null)
```

**`CompileLogic` & `RunLogic`**
Pre-compile and execute standalone JSON Logic expressions independently from a full schema structure. Useful for isolated logic execution.
```csharp
public ulong CompileLogic(string logicStr)
public JToken RunLogic(ulong logicId, string? data = null, string? context = null)
public JToken CompileAndRunLogic(string logicStr, string? data = null, string? context = null)
```

**`SetTimezoneOffset`**
Updates the timezone offset used for temporal operators (`today`, `now`, `dateformat`) during evaluation.
```csharp
public void SetTimezoneOffset(int? offsetMinutes) // e.g., 420 for UTC+7
```

**`ResolveLayout`**
Resolves UI layout nodes (`$layout` elements) independently from the main evaluation cycle.
```csharp
public void ResolveLayout(bool evaluate)
```

#### Schema Getters

Methods to retrieve the resolved internal state or parts of the schema after evaluation.

**Full Schema Retrieval**
```csharp
// Returns the fully evaluated schema as a JObject
public JObject GetEvaluatedSchema(bool skipLayout = false)

// Returns the schema stripped of the `$params` object
public JObject GetEvaluatedSchemaWithoutParams(bool skipLayout = false)

// Returns the evaluated schema as raw MessagePack bytes for high-performance zero-copy transfers
public byte[] GetEvaluatedSchemaMsgpack(bool skipLayout = false)
```

**Specific Path Retrieval**
Fetch specific parts of the evaluated state using a path (e.g., `#/properties/user`).
```csharp
public JToken GetEvaluatedSchemaByPath(string path, bool skipLayout = false)
public JObject GetEvaluatedSchemaByPaths(List<string> paths, bool skipLayout = false)
```

Fetch specific values from the original, un-evaluated schema structure.
```csharp
public JToken GetSchemaByPath(string path)
public JObject GetSchemaByPaths(List<string> paths)
```

**Root Value Retrieval**
Retrieve the resolved output `.value` of the root schema calculation.
```csharp
public JToken GetSchemaValue()
public JArray GetSchemaValueArray()
public JObject GetSchemaValueObject()
```

#### Lifecycle & Caching

Manage schema lifetimes and internal evaluation caches.

**Schema Reloading**
Hot-swap the underlying schema associated with the `JSONEval` instance without recreating the object interface.
```csharp
public void ReloadSchema(string schema, string? context = null, string? data = null)
public void ReloadSchemaMsgpack(byte[] schemaBytes, string? context = null, string? data = null)
public void ReloadSchemaFromCache(string cacheKey, string? context = null, string? data = null)
```

**Global Parsed Schema Cache**
Initialize directly from a pre-parsed, globally cached schema representation.
```csharp
public static JSONEval FromCache(string cacheKey, string? context = null, string? data = null)
```

**Evaluation Cache Management**
Manage the internal evaluation result cache for the current instance.
```csharp
public void EnableCache()
public void DisableCache()
public void ClearCache()
public bool IsCacheEnabled()
public JObject GetCacheStats() // Returns { entries, hits, misses, hit_rate }
public int GetCacheLength()
```

**Memory Management**
```csharp
public void Dispose()
```
Releases native Rust memory allocated for the instance. It is highly recommended to wrap `JSONEval` usage in a `using` block to ensure `Dispose()` is called automatically.

### Subform Methods

For managing isolated array items (Subforms).

#### `EvaluateSubform`

```csharp
public void EvaluateSubform(
    string subformPath, 
    string data, 
    string? context = null, 
    IEnumerable<string>? paths = null
)
```

-   **subformPath**: Schema reference to the array field (e.g., `#/line_items`).
-   **data**: Data for the single item being evaluated.
-   **paths**: Optional paths for selective evaluation within the subform.

#### `EvaluateDependentsSubform`

```csharp
public JArray EvaluateDependentsSubform(
    string subformPath, 
    string changedPath, 
    string? data = null, 
    string? context = null
)
```

## Platform Support

-   **.NET Standard 2.0+**
-   **.NET 6/7/8+**
-   **Platforms**: Windows (x64), Linux (x64), macOS (x64, ARM64)

## Performance & Concurrency

The library is thread-safe for **read interactions** but requires exclusive access for **write/evaluate** operations on the same instance. For high-concurrency server scenarios:

1.  **Parse Once, Reuse Many**: Parse the schema once and create a new `JSONEval` instance for each request using `JSONEval.FromCache`.
2.  **Dispose**: Always call `Dispose()` or use `using` blocks to prevent memory leaks.

```csharp
// Global initialization
var schemaKey = "main_schema";
// Assumes you have a way to pre-cache the schema (advanced usage)

// Per-request
using (var eval = JSONEval.FromCache(schemaKey)) 
{
    eval.Evaluate(requestData);
}
```
