@using System.Text.Json @using MudBlazor @using Microsoft.AspNetCore.Components.Forms Import Order JSON @if (ShowWarning) { Only valid VDA 5050 Order JSON is accepted.
Invalid structure will be rejected.
}
@if (!string.IsNullOrEmpty(ErrorMessage)) { @ErrorMessage }
Cancel Import
@code { [CascadingParameter] public IMudDialogInstance MudDialog { get; set; } = default!; public string JsonText { get; set; } = ""; public string? ErrorMessage; public bool ShowWarning { get; set; } private void Cancel() => MudDialog.Cancel(); // ================= FILE HANDLER ================= private async Task OnFileSelected(InputFileChangeEventArgs e) { ErrorMessage = null; ShowWarning = false; var file = e.File; if (file == null) return; if (!file.Name.EndsWith(".json", StringComparison.OrdinalIgnoreCase) && !file.Name.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)) { ShowWarning = true; ErrorMessage = "Only .json or .txt files are supported."; return; } try { using var stream = file.OpenReadStream(maxAllowedSize: 1_048_576); using var reader = new StreamReader(stream); JsonText = await reader.ReadToEndAsync(); StateHasChanged(); } catch (Exception ex) { ShowWarning = true; ErrorMessage = $"Failed to read file: {ex.Message}"; } } // ================= VALIDATE & IMPORT ================= private void ValidateAndImport() { ErrorMessage = null; ShowWarning = false; if (string.IsNullOrWhiteSpace(JsonText)) { ShowWarning = true; ErrorMessage = "JSON content is empty."; return; } try { using var doc = JsonDocument.Parse(JsonText); var root = doc.RootElement; // ===== BASIC STRUCTURE CHECK ===== if (!root.TryGetProperty("nodes", out _) || !root.TryGetProperty("edges", out _)) { throw new Exception("Missing 'nodes' or 'edges' field."); } var order = OrderMessage.FromSchemaObject(root); ValidateOrder(order); MudDialog.Close(DialogResult.Ok(order)); } catch (JsonException) { ShowWarning = true; ErrorMessage = "Invalid JSON format."; } catch (Exception ex) { ShowWarning = true; ErrorMessage = ex.Message; } } // ================= DOMAIN VALIDATION ================= private void ValidateOrder(OrderMessage order) { if (order.Nodes.Count == 0) throw new Exception("Order must contain at least one node."); if (order.Nodes.Count != order.Edges.Count + 1) throw new Exception( $"Invalid path structure: Nodes count ({order.Nodes.Count}) " + $"must equal Edges count + 1 ({order.Edges.Count + 1})." ); var nodeIds = order.Nodes .Select(n => n.NodeId) .ToHashSet(StringComparer.Ordinal); foreach (var e in order.Edges) { if (string.IsNullOrWhiteSpace(e.StartNodeId) || string.IsNullOrWhiteSpace(e.EndNodeId)) { throw new Exception( $"Edge '{e.EdgeId}' must define both StartNodeId and EndNodeId." ); } if (!nodeIds.Contains(e.StartNodeId)) throw new Exception( $"Edge '{e.EdgeId}' references unknown StartNodeId '{e.StartNodeId}'." ); if (!nodeIds.Contains(e.EndNodeId)) throw new Exception( $"Edge '{e.EdgeId}' references unknown EndNodeId '{e.EndNodeId}'." ); } } }