> From the [Strife developer docs](https://strife.app/docs/tutorials/getting-started/dotnet). Every page is listed in [llms.txt](https://strife.app/docs/llms.txt).

# .NET

Connect to the Strife API and interact with your data in a few steps:

### 1. Install Strife SDK

```bash
dotnet add package strife
```

### 2. Initialize Strife

> [!NOTE]
> The environment settings were provided during onboarding.

```json title="appsettings.json"
{
  "DocumentStoreSettings": {
    "Urls": "",
    "Database": "",
    "Certificate": "",
    "Password": ""
  },
  "Strife": {
    "Secret": "",
    "Workspace": "",
    "StartId": ""
  }
}
```

```csharp title="Program.cs"
using Strife;
using Strife.Routing;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddStrife();

var app = builder.Build();

app.UseRouting();

app.MapStrife();

app.Run();
```

### 3. Define a Collection and Template

A [Collection](https://ravendb.net/docs/article-page/7.0/csharp/client-api/faq/what-is-a-collection) is a group of records, called Documents, that all snapshot a common schema. You can define as many Collections as your application needs. Each Document in a Collection is stored in the Database based on the [Fields](https://strife.app/docs/reference/fields.md) that you define,  and is automatically queryable using a [Document session](https://ravendb.net/docs/article-page/7.0/nodejs/client-api/session/what-is-a-session-and-how-does-it-work).

Use the **Template Builder** in Strife Studio to define Collections and their templates. Then, create a corresponding C# model to represent your Collection in code.

> [!NOTE]
> A Collection in Strife should not confused with a Collection in RavenDB

```csharp
using Strife.Models;

public record BlogPost : Content {
    public string Heading { get; set; }
    public string Body { get;set; }
}
```

### 4. Rendering Content

When using the Strife SDK, content models are automatically resolved and passed to your controller actions without any manual fetching or lookup. Here's a typical example using an `BlogPostController`.

```csharp
using Microsoft.AspNetCore.Mvc;
using Strife.Binding;

public class BlogPostController : Controller
{
    public IActionResult Index([FromContentRoute] BlogPost content)
    {
        return View(content);
    }
}
```

#### How It Works

* **Automatic Content Binding**:\
  By using the `[FromContentRoute]` attribute, Strife automatically resolves and injects the correct `BlogPost` content based on the current route. You don't need to query for the content manually — it's handled for you.
* **Model-Driven Views**:\
  The resolved `BlogPost` instance is passed directly to the view, making it easy to render content using a strongly typed model.
* **Routing Integration**:\
  The system maps the incoming route to a specific content item (Document) and ensures that the correct type (e.g., BlogPost) is provided to your action.

Here’s a simplified example of how you might use the `BlogPost` model in a Razor view:

```cshtml
@model BlogPost

<h1>@Model.Heading</h1>
<div>@Model.Body</div>
```

By using `[FromContentRoute]`, you can focus on building views and logic without worrying about content retrieval. Strife takes care of resolving the right content based on the route and passing it into your controller actions.

### 5. Setup Real time preview

To enable real-time preview and connect your site to **Strife Studio**, include the Strife JavaScript SDK in your project.

Add the following to your HTML:

```html
<!DOCTYPE html>
  <html lang="sv">
    <head>
      <style>
        @@import 'https://unpkg.com/@@strifeapp/style' layer(strife);
      </style>
      <script type="module" defer>
        import 'https://unpkg.com/@@strifeapp/strife';
      </script>
    </head>
    <body>
```

Once connected, you can enable **Live Preview** in two ways:

* [**Using Strife Web Components**](https://strife.app/docs/reference/live-preview/web-components.md) for quick integration.
* [**Building a custom live preview implementation**](https://strife.app/docs/reference/live-preview/custom-live-preview-implementation.md) if you need more control over the preview experience.

This setup ensures that content editors can see real-time updates directly on the site as they work in Strife Studio.

#### Snapshots (optional)

Editors can hand a reviewer without a Strife account a **preview link** — `https://example.com/snapshot/{token}` — that shows a frozen, unpublished version of a document on your site for 7 days. Nothing to register: `MapStrife()` resolves the route, your controller receives the snapshot through `[FromContentRoute]` as usual, and `ContextService.GetSnapshot(HttpContext)` tells you when you are rendering one:

```csharp
var snapshot = _context.GetSnapshot(HttpContext);   // Strife.Services.SnapshotContext, or null
if (snapshot != null)
{
    // show a preview notice with snapshot.Name (render as text) and snapshot.ExpiresAt;
    // skip analytics and Open Graph tags
}
```

Expired, revoked or unknown links are your site's ordinary not-found. The route needs a `Content/ByUrl` index built from the `@strifeapp/strife` release that ships snapshots (run `strife push` after updating). Locale handling, the headers the SDK sets, and the CDN/analytics rules are in the [Snapshots](https://strife.app/docs/reference/snapshots.md) reference.

### 6. Querying and Searching

To **query** or **search** for documents, use the RavenDB client provided by the SDK. The `IDocumentStore` is available via **dependency injection** in your controllers and services.

Here’s an example of querying related documents in a controller:

```csharp
using Microsoft.AspNetCore.Mvc;
using Strife.Binding;

public class BlogListController : Controller
{
    private readonly IDocumentStore _store;
    public BlogListController(IDocumentStore store) {
        _store = store;
    }
    public IActionResult Index([FromContentRoute] BlogList content)
    {
        var viewModel = new BlogListViewModel(content);
        using (var session = _documentStore.OpenAsyncSession())
        {
            viewModel.CurrentPosts = await session.Query<BlogPost>(content.Posts);        
        }
        return View(viewModel);
    }
}.
```

> [!NOTE]
> `content.Posts` is assumed to be a list of BlogPost IDs stored in the `BlogList` document.
>
> Use `LoadAsync<T>()` when loading specific documents by ID, and `Query<T>()` for broader queries.

#### Full-Text Search Example

For more advanced search scenarios, such as full-text search with highlighting and scoring, you can query an index like this:

```csharp
var hits = await session.Query<Content_FullTextSearch.Result, Content_FullTextSearch>()
    .Search(x => x.SearchText, query, @operator: SearchOperator.And)
    .Highlight(x => x.SearchText, 100, 1, highlightingOptions, out Highlightings highlights)
    .OrderByScore()
    .Skip((page - 1) * pageSize)
    .Take(pageSize)
    .ProjectInto<SearchHit>()
    .Statistics(out QueryStatistics stats)
    .ToArrayAsync();
```

> [!NOTE]
> **Note:** A **full-text search index** (e.g., `Content_FullTextSearch`) **must be created manually** in RavenDB. Strife does **not** provide built-in search indexes — this allows you to define custom indexing logic suited to your content.

### Additional Resources

For more details on querying, indexing, and advanced search capabilities, see the [RavenDB official documentation](https://ravendb.net/docs/article-page/6.2/csharp/start/getting-started).
