Share via


針對 ASP.NET Core Blazor 表單進行疑難排解

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

本文提供 Blazor 表單的疑難排解指引。

大型表單承載和 SignalR 訊息大小限制

本節僅適用於實作 SignalR 的 Blazor Web Apps、Blazor Server 應用程式和裝載的 Blazor WebAssembly 方案。

如果表單處理失敗,因為元件的表單承載已超過中樞方法允許的傳入 SignalR 訊息大小上限,則表單可以採用 串流 JS Interop,而不會增加訊息大小限制。 如需大小限制和擲出錯誤的詳細資訊,請參閱 ASP.NET Core BlazorSignalR 指導

在下列範例中,文字區域 (<textarea>) 會與串流 JS Interop 搭配使用,以將最多 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 Core 中 JavaScript 位置Blazor 應用程式

基於安全性考量,串流 JS Interop 不允許長度為零的串流。 因此,如果提交表單時文字區域空白,則下列 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 中設定。

如需詳細資訊和指導,請參閱下列資源: