排查 ASP.NET Core Blazor 窗体问题

注意

此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本

警告

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

对于当前版本,请参阅此文的 .NET 8 版本

本文提供有关 Blazor 窗体的故障排除指南。

大型表单有效负载和 SignalR 消息大小限制

本部分仅适用于实现 SignalR 的 Blazor Web App、Blazor Server 应用和托管的 Blazor WebAssembly 解决方案。

如果因组件的表单有效负载已超过中心方法允许的最大传入 SignalR 消息大小而导致表单处理失败,表单可以采用流式传输 JS 互操作,而不增加消息大小限制。 有关大小限制和引发的错误的详细信息,请参阅 ASP.NET Core BlazorSignalR 指南

在以下示例中,文本区域 (<textarea>) 与流式传输 JS 互操作结合使用,可将最多 50,000 个字节的数据移动到服务器。

将 JavaScript (JS) getText 函数添加到应用:

window.getText = (elem) => {
  const textValue = elem.value;
  const utf8Encoder = new TextEncoder();
  const encodedTextValue = utf8Encoder.encode(textValue);
  return encodedTextValue;
};

有关在 Blazor 应用中放置“JS”的信息,请参阅“ASP.NET CoreBlazor 应用中的 JavaScript 位置”。

出于安全考虑,零长度流不允许用于流式传输 JS 互操作。 因此,如果提交表单时文本区域是空白的,下面的 StreamFormData 组件将捕获 JSException 并返回一个空字符串。

StreamFormData.razor

@page "/stream-form-data"
@inject IJSRuntime JS
@inject ILogger<StreamFormData> Logger

<h1>Stream form data with JS interop</h1>

<EditForm FormName="StreamFormData" Model="this" OnSubmit="Submit">
    <div>
        <label>
            &lt;textarea&gt; value streamed for assignment to
            <code>TextAreaValue (&lt;= 50,000 characters)</code>:
            <textarea @ref="largeTextArea" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

<div>
    Length: @TextAreaValue?.Length
</div>

@code {
    private ElementReference largeTextArea;

    public string? TextAreaValue { get; set; }

    protected override void OnInitialized() =>
        TextAreaValue ??= string.Empty;

    private async Task Submit()
    {
        TextAreaValue = await GetTextAsync();

        Logger.LogInformation("TextAreaValue length: {Length}",
            TextAreaValue.Length);
    }

    public async Task<string> GetTextAsync()
    {
        try
        {
            var streamRef =
                await JS.InvokeAsync<IJSStreamReference>("getText", largeTextArea);
            var stream = await streamRef.OpenReadStreamAsync(maxAllowedSize: 50_000);
            var streamReader = new StreamReader(stream);

            return await streamReader.ReadToEndAsync();
        }
        catch (JSException jsException)
        {
            if (jsException.InnerException is
                    ArgumentOutOfRangeException outOfRangeException &&
                outOfRangeException.ActualValue is not null &&
                outOfRangeException.ActualValue is long actualLength &&
                actualLength == 0)
            {
                return string.Empty;
            }

            throw;
        }
    }
}
@page "/stream-form-data"
@inject IJSRuntime JS
@inject ILogger<StreamFormData> Logger

<h1>Stream form data with JS interop</h1>

<EditForm Model="this" OnSubmit="Submit">
    <div>
        <label>
            &lt;textarea&gt; value streamed for assignment to
            <code>TextAreaValue (&lt;= 50,000 characters)</code>:
            <textarea @ref="largeTextArea" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

<div>
    Length: @TextAreaValue?.Length
</div>

@code {
    private ElementReference largeTextArea;

    public string? TextAreaValue { get; set; }

    protected override void OnInitialized() => 
        TextAreaValue ??= string.Empty;

    private async Task Submit()
    {
        TextAreaValue = await GetTextAsync();

        Logger.LogInformation("TextAreaValue length: {Length}",
            TextAreaValue.Length);
    }

    public async Task<string> GetTextAsync()
    {
        try
        {
            var streamRef =
                await JS.InvokeAsync<IJSStreamReference>("getText", largeTextArea);
            var stream = await streamRef.OpenReadStreamAsync(maxAllowedSize: 50_000);
            var streamReader = new StreamReader(stream);

            return await streamReader.ReadToEndAsync();
        }
        catch (JSException jsException)
        {
            if (jsException.InnerException is
                    ArgumentOutOfRangeException outOfRangeException &&
                outOfRangeException.ActualValue is not null &&
                outOfRangeException.ActualValue is long actualLength &&
                actualLength == 0)
            {
                return string.Empty;
            }

            throw;
        }
    }
}

如果因组件的表单有效负载已超过中心方法允许的最大传入 SignalR 消息大小而导致表单处理失败,可以增加消息大小限制。 有关大小限制和引发的错误的详细信息,请参阅 ASP.NET Core BlazorSignalR 指南

EditForm 参数错误

InvalidOperationException:EditForm 需要 Model 参数或 EditContext 参数,但不能同时需要这两个参数。

确认 EditForm 是否分配 ModelEditContext。 不要对同一窗体使用这两者。

在分配给 Model 时,请确认模型类型是否已实例化。

已断开连接

错误:连接断开,出现错误“错误:服务器关闭时返回错误:连接因错误而关闭。”

System.IO.InvalidDataException:超出了最大消息大小 32768B。 消息大小可以在 AddHubOptions 中配置。

有关详细信息和指南,请参阅以下资源: