diff --git a/README.md b/README.md
index 25a78ee..fdb2e59 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ A security-first Blazor iframe component with automatic resizing, cross-frame me
- **Security-First Design** - Built-in origin validation, message filtering, and sandbox isolation
- **Content Security Policy** - Comprehensive CSP integration with fluent configuration API
-- **Cross-Frame Messaging** - Secure postMessage communication with validation
+- **Bidirectional Communication** - Secure postMessage communication with validation for both directions
- **Sandbox Support** - Multiple security levels from permissive to paranoid isolation
- **Environment-Aware** - Different configurations for development vs production
- **Automatic Resizing** - Smart height adjustment based on iframe content
@@ -57,13 +57,18 @@ dotnet add package BlazorFrame
-
-
+
+
+
@code {
+ private BlazorFrame? iframeRef;
+
private readonly MessageSecurityOptions securityOptions = new MessageSecurityOptions()
.ForProduction() // Strict security settings
.WithBasicSandbox() // Enable iframe sandboxing
@@ -79,7 +84,15 @@ dotnet add package BlazorFrame
{
Console.WriteLine($"Security violation: {violation.ValidationError}");
return Task.CompletedTask;
- };
+ }
+
+ private async Task SendDataToIframe()
+ {
+ if (iframeRef != null)
+ {
+ await iframeRef.SendTypedMessageAsync("user-data", new { userId = 123, name = "John" });
+ }
+ }
}
```
diff --git a/docs/configuration/communication-options.md b/docs/configuration/communication-options.md
index 0707fcb..c68b3e4 100644
--- a/docs/configuration/communication-options.md
+++ b/docs/configuration/communication-options.md
@@ -2,45 +2,87 @@
**Cross-frame messaging and event handling for BlazorFrame**
-This guide covers all aspects of configuring communication between your Blazor application and iframe content, including message validation, origin control, and event handling.
+This guide covers all aspects of configuring communication between your Blazor application and iframe content, including message validation, origin control, event handling, and **bidirectional communication**.
## Message Handling Overview
-BlazorFrame provides two main approaches to handling messages:
+BlazorFrame provides comprehensive communication capabilities:
-- **Validated Messages** (`OnValidatedMessage`) - Recommended for new implementations
+- **Iframe -> Host** (`OnValidatedMessage`) - Receive messages from iframe with validation
+- **Host -> Iframe** (`SendMessageAsync`) - Send messages to iframe with security validation
- **Raw Messages** (`OnMessage`) - Legacy support for simple scenarios
## Basic Message Configuration
-### Essential Message Handling
+### Bidirectional Communication
```razor
-
+
+
+
@code {
- private readonly MessageSecurityOptions messageOptions = new MessageSecurityOptions()
- .ForProduction()
- .WithBasicSandbox();
+ private BlazorFrame? iframeRef;
- private async Task HandleValidatedMessage(IframeMessage message)
+ // Send structured data to iframe
+ private async Task SendDataToIframe()
{
- Logger.LogInformation("Received message from {Origin}: {Data}",
- message.Origin, message.Data);
-
- // Process the validated message
- await ProcessMessage(message);
+ if (iframeRef == null) return;
+
+ var success = await iframeRef.SendMessageAsync(new
+ {
+ type = "data-update",
+ timestamp = DateTime.UtcNow,
+ data = new
+ {
+ userId = currentUser.Id,
+ preferences = currentUser.Preferences,
+ theme = currentTheme
+ }
+ });
+
+ if (success)
+ {
+ Logger.LogInformation("Data sent successfully to iframe");
+ }
}
- private async Task HandleSecurityViolation(IframeMessage violation)
+ // Send typed messages with automatic structure
+ private async Task SendNotification()
{
- Logger.LogWarning("Security violation: {Error}", violation.ValidationError);
-
- // Handle security issues
- await HandleSecurityIssue(violation);
+ await iframeRef.SendTypedMessageAsync("notification", new
+ {
+ message = "Hello from host!",
+ level = "info",
+ timestamp = DateTimeOffset.UtcNow
+ });
+ }
+
+ private async Task HandleMessage(IframeMessage message)
+ {
+ if (message.MessageType == "request-user-data")
+ {
+ // Respond to iframe's request for user data
+ await SendUserDataToIframe();
+ }
+ }
+
+ private async Task SendUserDataToIframe()
+ {
+ await iframeRef.SendTypedMessageAsync("user-data-response", new
+ {
+ user = new
+ {
+ id = currentUser.Id,
+ name = currentUser.Name,
+ email = currentUser.Email,
+ permissions = currentUser.Permissions
+ }
+ });
}
}
```
@@ -336,139 +378,6 @@ public class MessageProcessor
}
```
-## Bidirectional Communication
-
-### Sending Messages to Iframe
-
-```razor
-
-
-
-
-@code {
- private BlazorFrame? iframeRef;
-
- private async Task SendDataToIframe()
- {
- if (iframeRef == null) return;
-
- var messageData = new
- {
- type = "data-update",
- timestamp = DateTime.UtcNow,
- data = new
- {
- userId = currentUser.Id,
- preferences = currentUser.Preferences,
- theme = currentTheme
- }
- };
-
- await iframeRef.SendMessageAsync(messageData);
- }
-
- private async Task HandleMessage(IframeMessage message)
- {
- if (message.MessageType == "request-user-data")
- {
- // Respond to iframe's request for user data
- await SendUserDataToIframe();
- }
- }
-
- private async Task SendUserDataToIframe()
- {
- var userData = new
- {
- type = "user-data-response",
- user = new
- {
- id = currentUser.Id,
- name = currentUser.Name,
- email = currentUser.Email,
- permissions = currentUser.Permissions
- }
- };
-
- await iframeRef.SendMessageAsync(userData);
- }
-}
-```
-
-### Request-Response Pattern
-
-```razor
-@code {
- private readonly Dictionary> pendingRequests = new();
-
- private async Task SendRequestToIframe(string requestType, object data)
- {
- var requestId = Guid.NewGuid().ToString();
- var tcs = new TaskCompletionSource