### Install Hydro Package
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Install the Hydro package using the .NET CLI for ASP.NET Core projects.
```console
dotnet add package Hydro
```
--------------------------------
### Sample Program.cs with Hydro Integration
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/introduction/getting-started.md
An example of a `Program.cs` file demonstrating the integration of Hydro services and middleware within an ASP.NET Core application.
```csharp
using Hydro.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddHydro(); // Hydro
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.UseHydro(); // Hydro
app.Run();
```
--------------------------------
### Basic Hydro View Implementation
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Implement the HTML structure for a Hydro view. This example shows a simple submit button.
```razor
@model Submit
```
--------------------------------
### VitePress Custom Container Examples
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/markdown-examples.md
Shows the markdown syntax for creating custom info, tip, warning, danger, and details containers in VitePress.
```md
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
```
--------------------------------
### Usage Example: Passing a Lambda as a Click Handler
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Example of how to use the `FormButton` view by passing a lambda expression to the `click` attribute.
```razor
Save
```
--------------------------------
### Action with Integer Parameter
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
Actions can accept parameters. This example shows a `Set` action that takes an integer to update the `Count` property.
```csharp
public class Counter : HydroComponent
{
public int Count { get; set; }
public void Set(int newValue)
{
Count = newValue;
}
}
```
--------------------------------
### Hydro Action Loading Indicator
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/ui-utils.md
This CSS and Razor example demonstrates how to show a loading indicator within a button when a Hydro operation is in progress, using the `.hydro-request` class.
```css
/* MyComponent.cshtml.css */
.loader {
display: none;
}
.hydro-request .loader {
display: inline-block;
}
```
```razor
@model MyComponent
```
--------------------------------
### Hydro View Parameter Implementation
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Implement the HTML structure for a Hydro view that uses parameters. This example displays a message within an alert div.
```razor
@model Alert
@Model.Message
```
--------------------------------
### Using a Hydro View
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Integrate a defined Hydro view into another Razor view by using its tag-like syntax. This example uses the `Submit` view.
```razor
```
--------------------------------
### Razor Form with Validation and Binding
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/index.md
Shows a complete form example in Razor Pages using Hydro. It includes input binding (`bind`), validation (`asp-validation-for`), and form submission handling (`on:submit`).
```razor
@model NameForm
```
```csharp
// NameForm.cs
public class NameForm : HydroComponent
{
[Required, MaxLength(50)]
public string Name { get; set; }
public string Message { get; set; }
public void Save()
{
if (!Validate())
{
return;
}
Message = "Success!";
Name = "";
}
}
```
--------------------------------
### Define a Hydro Component (C# Class)
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Define the server-side logic for a Hydro component by creating a C# class that inherits from `HydroComponent`. This example implements the `Add` method for the counter.
```csharp
// Counter.cs
public class Counter : HydroComponent
{
public int Count { get; set; }
public void Add()
{
Count++;
}
}
```
--------------------------------
### Define a Hydro Component (Razor View)
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Define the UI for a Hydro component using a Razor view (`.cshtml` file). This example shows a simple counter component.
```razor
@model Counter
Count: @Model.Count
```
--------------------------------
### Usage: Passing Dynamic HTML Attributes to a Hydro View
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Example of using the `Alert` view and passing an additional `class` attribute that will be rendered dynamically.
```razor
```
--------------------------------
### Configure Long Polling with Custom Interval
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/long-polling.md
Decorate a parameterless action with the [Poll] attribute and set the Interval property to customize the polling frequency in milliseconds. This example polls every 60 seconds.
```csharp
public class NotificationsIndicator(INotifications notifications) : HydroComponent
{
public int NotificationsCount { get; set; }
[Poll(Interval = 60_000)]
public async Task Refresh()
{
NotificationsCount = await notifications.GetCount();
}
}
```
--------------------------------
### Razor Input Binding Example
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/index.md
Demonstrates how to bind an input element to a model property in Razor Pages using Hydro's `bind:keydown` directive. This updates the model as the user types.
```razor
@model NameForm
Hello @Model.Name
```
```csharp
// NameForm.cs
public class NameForm : HydroComponent
{
public string Name { get; set; }
}
```
--------------------------------
### Binding Action with JavaScript Parameter
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
This Razor example shows how to bind a button click to an action that accepts a parameter evaluated by JavaScript. `window.myInput.value` is executed client-side, and its result is passed to the `Update` action.
```razor
@model Content
```
--------------------------------
### Create ASP.NET Core Web App
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Create a new ASP.NET Core web application using the .NET CLI.
```console
dotnet new webapp -o MyApp
cd MyApp
```
--------------------------------
### Configure Hydro Services and Middleware
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Add Hydro services to the dependency injection container and configure its middleware in the application's startup code.
```csharp
builder.Services.AddHydro();
...
app.UseHydro(builder.Environment);
```
--------------------------------
### Configure Hydro Services and Middleware
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/introduction/getting-started.md
Register Hydro services and middleware in your application's startup code. Ensure `UseHydro` is called after `UseStaticFiles` and `UseRouting`.
```csharp
builder.Services.AddHydro();
```
```csharp
app.UseHydro();
```
--------------------------------
### JavaScript Syntax Highlighting with Line Highlight
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/markdown-examples.md
Demonstrates JavaScript code with a specific line highlighted using Shiki syntax highlighting.
```js
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
--------------------------------
### Create a Hydro Component's View
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/components.md
Create the UI for a Hydro component using a .cshtml file. The component's class should be set as the view model. Ensure a single root element and use `Model` to access component state.
```razor
@model PageCounter
Count: @Model.Count
```
--------------------------------
### Listen for Hydro Component Initialization Event
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/js.md
Attach an event listener to the document to catch the 'HydroComponentInit' event, which is triggered after a component is initialized. The event detail contains information about the initialized component.
```javascript
document.addEventListener('HydroComponentInit', function (e) {
console.log('Component initialized', e.detail);
});
```
--------------------------------
### Render Component with Available Parameters
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/parameters.md
Demonstrates how to render a component when certain properties are marked as not bound. Only the bound properties (like 'name') will be available for passing values.
```razor
@* Ok *@@
@* Currencies won't be passed *@
```
--------------------------------
### Hydro Component Lifecycle and Event Handling
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/components.md
Implement component lifecycle methods like `MountAsync` and `Render`, and handle custom events by subscribing in the constructor. Services can be injected via dependency injection.
```csharp
public class EditUserForm : HydroComponent
{
private readonly IDatabase _database;
public EditUserForm(IDatabase database)
{
_database = database;
Subscribe(Handle);
}
public string UserId { get; set; }
[Required]
public string Name { get; set; }
public override async Task MountAsync()
{
var formData = ...; // fetch data from database
Name = formData.Name;
}
public override void Render()
{
ViewBag.IsLongName = Name.Length > 20;
}
public async Task Save()
{
await _database.UpdateUser(UserId, Name); // save the data
}
public void Handle(SystemMessageEvent message)
{
Message = message.Text;
}
}
```
--------------------------------
### Handle Multiple Files Upload in Component
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/binding.md
Adapt the component to handle multiple files by changing the property type to an array (`IFormFile[]`) and iterating through the uploaded files in `BindAsync`. Each file is processed and its temporary ID is stored.
```csharp
// AddAttachment.cshtml.cs
public class AddAttachment : HydroComponent
{
[Transient]
public IFormFile[] DocumentFiles { get; set; }
[Required]
public List DocumentIds { get; set; }
public override async Task BindAsync(PropertyPath property, object value)
{
if (property.Name == nameof(DocumentFiles))
{
DocumentIds = [];
var files = (IFormFile[])value;
foreach (var file in files)
{
DocumentIds.Add(await GetStoredTempFileId(file));
}
}
}
// rest of the file same as in the previous example
}
```
--------------------------------
### Implement Caching for Customer Data
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/parameters.md
This C# code demonstrates how to use the `Cache` method to create a cached property for fetching customer data. It includes logic for filtering based on a search phrase and accessing the cached value.
```csharp
// CustomerList.cshtml.cs
public class CustomerList(IDatabase database) : HydroComponent
{
public string SearchPhrase { get; set; }
public HashSet Selection { get; set; } = new();
public Cache>> Customers => Cache(async () =>
{
var query = database.Query();
if (!string.IsNullOrWhiteSpace(SearchPhrase))
{
query = query.Where(p => p.Name.Contains(SearchPhrase));
}
return await query.ToListAsync();
});
public async Task Print()
{
var customers = await Customers.Value;
if (!customers.Any())
{
return;
}
var customerIds = customers.Select(c => c.Id).ToList();
Location(Url.Page("/Customers/Print"), new CustomersPrintPayload(customerIds));
}
}
```
--------------------------------
### Include Hydro JavaScript Files
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Add Hydro and Alpine.js script references to the head section of your layout file for client-side functionality.
```html
```
--------------------------------
### Hydro View with Parameters
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Define a Hydro view that accepts parameters. The `Message` property is exposed and can be passed from the parent view.
```csharp
public class Alert : HydroView
{
public string Message { get; set; }
}
```
--------------------------------
### Read and Write String Cookies
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/cookies.md
Use CookieStorage.Get to read a cookie with a default value and CookieStorage.Set to write a cookie.
```csharp
// ThemeSwitcher.cshtml.cs
public class ThemeSwitcher : HydroComponent
{
public string Theme { get; set; }
public override void Mount()
{
Theme = CookieStorage.Get("theme", defaultValue: "light");
}
public void Switch(string theme)
{
Theme = theme;
CookieStorage.Set("theme", theme);
}
}
```
--------------------------------
### Returning ComponentResults.File
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
The `ComponentResults.File` result allows an action to return a file from the server. Specify the file path and media type.
```csharp
// ShowInvoice.cshtml.cs
public class ShowInvoice : HydroComponent
{
public IComponentResult Download()
{
return ComponentResults.File("./storage/file.pdf", MediaTypeNames.Application.Pdf);
}
}
```
--------------------------------
### Define a Parent Hydro Component with an Action
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Define a `Parent` Hydro component with a `LoadText` method that can be called from a child view.
```csharp
public class Parent : HydroComponent
{
public string Value { get; set; }
public void LoadText(string value)
{
Value = value;
}
}
```
--------------------------------
### Subscribe to an Event for Re-rendering
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/events.md
Use this when you only need to re-render a component when a specific event occurs. No explicit handler is needed.
```csharp
// ProductList.cshtml.cs
public class ProductList : HydroComponent
{
public ProductList()
{
Subscribe();
}
public override void Render()
{
// When ProductAddedEvent occurs, component will be rerendered
}
}
```
--------------------------------
### Force Re-render with Key Parameter
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/parameters.md
Demonstrates how to use the 'key' parameter to force a re-render of a component when its associated data changes. The key should be a unique identifier for the data, such as a hash code.
```razor
```
--------------------------------
### Define a Hydro Component's Code-Behind
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/components.md
Define the logic and state for a Hydro component by inheriting from `HydroComponent`. Use properties to hold state and methods to handle actions.
```csharp
// ~/Pages/Components/PageCounter.cshtml.cs
public class PageCounter : HydroComponent
{
public int Count { get; set; }
public void Add()
{
Count++;
}
}
```
--------------------------------
### Render Component with Key Argument
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/parameters.md
Shows how to provide an optional 'key' argument when rendering a Hydro component. This is used to distinguish between multiple components of the same type during DOM updates.
```razor
```
```razor
```
--------------------------------
### Use Key for Multiple Components of Same Type
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/parameters.md
Illustrates using the 'key' parameter within a loop to assign unique keys to multiple instances of the same component type, enabling proper DOM updates.
```razor
@foreach (var item in Items)
{
}
```
```razor
```
--------------------------------
### Initiate Navigation from Component (No Reload)
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/navigation.md
Call the `Location` method within a Hydro component to navigate to a new page without a full page reload. Ensure the target URL is correctly specified.
```csharp
// MyPage.cshtml.cs
public class MyPage : HydroComponent
{
public void About()
{
Location(Url.Page("/About/Index"));
}
}
```
--------------------------------
### Returning ComponentResults.Challenge
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
Use `ComponentResults.Challenge` to initiate an authentication challenge, typically for external providers like GitHub. Authentication properties and schemes can be specified.
```csharp
// Profile.cshtml.cs
public class Profile : HydroComponent
{
public IComponentResult LoginWithGitHub()
{
var properties = new AuthenticationProperties
{
RedirectUri = RedirectUri,
IsPersistent = true
};
return ComponentResults.Challenge(properties, [GitHubAuthenticationDefaults.AuthenticationScheme]);
}
}
```
--------------------------------
### Basic Hydro View Definition
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Define a basic Hydro view by inheriting from the `HydroView` class. This sets up the component for use within Hydro.
```csharp
public class Submit : HydroView;
```
--------------------------------
### Configure Hydro for Targeted Content Updates
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/navigation.md
In your layout file, include Hydro's configuration and scripts. In your page, conditionally set `Layout = null` and use `HydroTarget` to specify where the new content should be injected, preventing a full page reload.
```razor
// Layout.cshtml
Test
```
```razor
// Index.cshtml
@{
if (HttpContext.IsHydro())
{
Layout = null;
this.HydroTarget("#content");
}
}
Content of the page
```
--------------------------------
### Enable Anti-forgery Token in Hydro Configuration
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/xsrf-token.md
Enable the anti-forgery token feature by setting `AntiforgeryTokenEnabled` to `true` in your Hydro service configuration. This is a crucial step for preventing XSRF attacks.
```csharp
services.AddHydro(options =>
{
options.AntiforgeryTokenEnabled = true;
});
```
--------------------------------
### Render Hydro Component using Extension Method
Source: https://github.com/hydrostack/hydro/blob/main/README.md
Render a Hydro component in a Razor Page by calling the `Html.Hydro` extension method.
```razor
...
@await Html.Hydro("Counter")
...
```
--------------------------------
### Define a Simple Action Method
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
Define a C# method in your Hydro component class to be used as an action. This method will be invoked when a corresponding browser event occurs.
```csharp
public class Counter : HydroComponent
{
public int Count { get; set; }
public void Add()
{
Count++;
}
}
```
--------------------------------
### Handle Single File Upload in Component
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/binding.md
Process a single uploaded file in the `BindAsync` method. The `[Transient]` attribute prevents the file from being serialized and sent back to the server unnecessarily. Files are stored temporarily.
```csharp
// AddAttachment.cshtml.cs
public class AddAttachment : HydroComponent
{
[Transient]
public IFormFile DocumentFile { get; set; }
[Required]
public string DocumentId { get; set; }
public async Task Save()
{
if (!Validate())
{
return;
}
var tempFilePath = GetTempFileLocation(DocumentId);
// Move your file at tempFilePath to the final storage
// and save that information in your domain
}
public override async Task BindAsync(PropertyPath property, object value)
{
if (property.Name == nameof(DocumentFile))
{
// assign the temp file name to the DocumentId
DocumentId = await GetStoredTempFileId((IFormFile)value);
}
}
private static async Task GetStoredTempFileId(IFormFile file)
{
if (file == null)
{
return null;
}
var tempFileName = Guid.NewGuid().ToString("N");
var tempFilePath = GetTempFileLocation(tempFileName);
await using var readStream = file.OpenReadStream();
await using var writeStream = File.OpenWrite(tempFilePath);
await readStream.CopyToAsync(writeStream);
return tempFileName;
}
private static string GetTempFileLocation(string fileName) =>
Path.Combine(Path.GetTempPath(), fileName);
}
```
--------------------------------
### Define a Hydro View with an Event Handler
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Define a `FormButton` Hydro view that accepts a click handler via the `Expression` type.
```csharp
// FormButton.cshtml.cs
public class FormButton : HydroView
{
public Expression Click { get; set; }
}
```
--------------------------------
### Hydro View Manual Naming
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Define a Hydro view using manual naming with PascalCase and `nameof` to explicitly target the element name. This allows for direct mapping of class names to HTML tags.
```csharp
[HtmlTargetElement(nameof(SubmitButton))]
public class SubmitButton : HydroView;
```
--------------------------------
### Razor Component for Click Actions
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/index.md
Illustrates a simple counter component in Razor Pages using Hydro. It demonstrates how to handle click events (`on:click`) to call server-side methods and update the UI.
```razor
@model Counter
Count: @Model.Count
```
```csharp
// Counter.cs
public class Counter : HydroComponent
{
public int Count { get; set; }
public void Add(int value)
{
Count += value;
}
}
```
--------------------------------
### Define a Hydro View with a Message Property
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Define an `Alert` Hydro view with a `Message` property and a dynamic `class` attribute.
```csharp
// Alert.cshtml.cs
public class Alert : HydroView
{
public string Message { get; set; }
}
```
--------------------------------
### Initiate Navigation with Full Page Reload
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/navigation.md
Use the `Redirect` method within a Hydro component to perform a full page reload and navigate to a new URL. This is suitable for actions that require a complete refresh, such as logging out.
```csharp
// MyPage.cshtml.cs
public class MyPage : HydroComponent
{
public void Logout()
{
// logout logic
Redirect(Url.Page("/Home/Index"));
}
}
```
--------------------------------
### Global Event Dispatch in C#
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/events.md
Publish events to all components in the application, regardless of their hierarchy. Use when multiple unrelated components need to be notified.
```csharp
Dispatch(new ShowMessage(Content), Scope.Global);
```
```csharp
DispatchGlobal(new ShowMessage(Content));
```
--------------------------------
### Configure Data Protection Key Persistence with Entity Framework Core
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/advanced/load-balancing.md
Use this configuration to persist data protection keys to a database using Entity Framework Core. This ensures keys are shared across all nodes in a load-balanced environment.
```csharp
services.AddDataProtection()
.PersistKeysToDbContext();
```
--------------------------------
### Binding Action with Integer Parameter
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
This Razor snippet demonstrates how to call an action method with an integer parameter using the `on:click` tag helper.
```razor
@model Counter
Count: @Model.Count
```
--------------------------------
### Parent Component Razor View
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/utilities/hydro-views.md
Basic Razor view for the `Parent` component, including a placeholder for a child view.
```razor
@model Parent
```
--------------------------------
### Customize Cookie Options
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/cookies.md
Pass a CookieOptions instance to CookieStorage.Set to further customize cookie settings like Secure.
```csharp
CookieStorage.Set("theme", "light", encrypt: false, new CookieOptions { Secure = true });
```
--------------------------------
### Page Loading Indicator
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/ui-utils.md
This CSS and HTML sets up a visual indicator for page loading using the `.hydro-loading` class. The animation `loadPage` defines the loading bar's behavior.
```html
```
--------------------------------
### Bind Input Elements Using `bind`
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/binding.md
Use the `bind` attribute on input elements to synchronize their values with component properties. The `asp-for` tag helper is used here for convenience.
```razor
```
--------------------------------
### Event and Expression Syntax
Source: https://github.com/hydrostack/hydro/blob/main/docs/content/features/actions.md
The `on` attribute follows the format `on:event="expression"`, where `event` is compatible with Alpine.js's `x-on` directive and `expression` is a C# lambda calling a callback method.
```razor