标签: blazor-server-side

从任意线程调用StateHasChanged()是否安全?

StateHasChanged()从任意线程调用安全吗?

让我给你一些背景。想象一下您拥有的服务器端Blazor / Razor组件应用程序:

  • 单例服务NewsProvider,它BreakingNews从任意线程引发事件。
  • 一个组件News.cshtml是可以获得的服务注入和订阅BreakingNews事件。引发事件时,组件将更新模型并调用StateHashChanged()

NewsProvider.cs

using System;
using System.Threading;

namespace BlazorServer.App
{
    public class BreakingNewsEventArgs: EventArgs
    {
        public readonly string News;

        public BreakingNewsEventArgs(string news)
        {
            this.News = news;
        }
    }

    public interface INewsProvider
    {
        event EventHandler<BreakingNewsEventArgs> BreakingNews;
    }

    public class NewsProvider : INewsProvider, IDisposable
    {

        private int n = 0;

        public event EventHandler<BreakingNewsEventArgs> BreakingNews;
        private Timer timer;

        public NewsProvider()
        {
            timer = new Timer(BroadCastBreakingNews, null, 10, 2000);

        } …
Run Code Online (Sandbox Code Playgroud)

c# blazor blazor-server-side

8
推荐指数
1
解决办法
2343
查看次数

C# Blazor 和数据绑定到 DateTime?

我必须为现有Asp.net Core 3.1 Blazor项目的日期和时间输入字段添加数据验证;这是我第一次与 Blazor 合作。

我在日期输入字段(具有日期选择器和绑定到日期时间变量的数据)上设置了数据绑定,没有任何问题。但是,时间输入的情况不同(它有一个时间选择器并绑定到另一个 DateTime 变量。)

简而言之,当用户使用时间选择器设置时间并将其关闭时,输入字段中的时间将返回到最初设置的时间。例如,如果时间输入当前设置为上午 12:00,然后用户从时间选择器中选择新时间(假设下午 2:00),则用户单击“确定”并关闭时间选择器,输入中的时间回到中午 12:00。我在同一页面上有另一个时间输入,但数据绑定到字符串而不是日期时间,如果在时间选择器中再次设置时间,则保留时间。

我写了一个很短的程序来演示这个问题。我的示例页面有三个输入字段:日期、时间和另一个时间,但其数据绑定到字符串。

在此输入图像描述

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="wrapper">
  <section class="createevent">
    <EditForm EditContext="@_editContext" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">
      <DataAnnotationsValidator />
      <div class="form-group">
        <p>
          <label>
            Date:
          </label>
          <input id="txtDate" type="date" required @bind-value="_timeSample.date" />
          <ValidationMessage For="@(() => _timeSample.date)" />
        </p>
      </div>
      <div class="form-group">
        <p>
          <label>
            Time:
          </label>
          <input id="txtTime" type="time" required @bind="_timeSample.time" />
          <ValidationMessage For="@(() => _timeSample.time)" />
        </p>
      </div>
      <div class="form-group">
        <p>
          <label>
            Time2:
          </label>
          <InputText …
Run Code Online (Sandbox Code Playgroud)

c# blazor blazor-server-side blazor-client-side asp.net-blazor

8
推荐指数
1
解决办法
2万
查看次数

在 Blazor 服务器端如何检测用户是否尝试离开当前页面

我正在开发一个 ASP.NET Core 3.1 Blazor 服务器端应用程序,该应用程序具有带有 EditForm 的 Blazor 组件。我想警告用户,如果他们尝试导航离开页面(即单击浏览器后退按钮或选择导航菜单来加载同一应用程序中的另一个页面),他们有未保存的数据。

读过有关使用 javascript window.onbeforeunload 的帖子,但我不确定在 Blazor 服务器端调用 javascript 是否会扰乱 SignalR 连接。

我还阅读了有关使用 CircuitHandler 的帖子,但我不确定如果用户只是移动到同一应用程序中的不同页面,SignalR 电路是否会发生变化。

关于如何最好地处理这一要求有什么建议吗?

javascript signalr asp.net-core blazor blazor-server-side

8
推荐指数
1
解决办法
7767
查看次数

Blazor - 在运行时更改 UI CultureInfo

我需要根据每种文化的资源文件在运行时更改文化。

预期的

用户单击从当前语言切换到另一种语言的按钮。页面中的文本根据每种文化的资源文件进行刷新。

实际的

用户单击从当前语言切换到另一种语言的按钮。页面中的文本根据每种文化的资源文件进行刷新。一旦用户对任何组件(我有几个单选按钮、按钮和复选框)执行任何操作,文本就会返回到第一次编写的内容。就像 CultureInfo 根本没有改变一样。

尝试

创建一个注入到组件的 AppState 类

    public class AppState
{
    public CultureInfo currentCulture { get; private set; } = CultureInfo.CurrentCulture;
    public event Action OnChange;
    public void ChangeCulture(CultureInfo newCulture)
    {
        currentCulture = newCulture;
        System.Threading.Thread.CurrentThread.CurrentCulture.ClearCachedData();
        System.Threading.Thread.CurrentThread.CurrentUICulture.ClearCachedData();
        System.Threading.Thread.CurrentThread.CurrentCulture = newCulture;
        System.Threading.Thread.CurrentThread.CurrentUICulture = newCulture;
        NotifyStateChanged();
    }

    public CultureInfo getCurrentCulture()
    {
        if (currentCulture == null)
        {
            ChangeCulture(CultureInfo.CurrentCulture);
        }
        return currentCulture;

    }

    private void NotifyStateChanged() => OnChange?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

还在startup.cs和AppState instante中添加了项目的本地化

        services.AddScoped<AppState>();
        services.AddMvc().AddMvcLocalization();
        services.AddLocalization();
        var supportedCultures = new List<CultureInfo> { …
Run Code Online (Sandbox Code Playgroud)

c# localization blazor blazor-server-side

8
推荐指数
1
解决办法
7730
查看次数

如何在 blazor 服务器端应用程序中检测移动设备?

我需要检测 blazor 服务器端应用程序的用户是否正在使用移动设备。有什么办法可以查出用户正在使用哪个设备?

我知道我可以使用 JSRuntime 来完成,但是有什么方法可以使用纯 C# 来解决这个问题吗?

c# asp.net-core blazor blazor-server-side

8
推荐指数
2
解决办法
7957
查看次数

.NET core 5.0 支架登录页面显示“The returnUrl field is required”(Blazor 服务器端)

我有一个运行 Blazor 服务器的 .net 5.0 预览版 7 项目,并且身份登录工作正常,直到我搭建了身份登录页面。The returnUrl field is required.现在,一旦加载登录页面,我就会收到表单错误消息

当我调试OnGetAsyncLogin.cshtml.cs 中的方法时,它显示 returnUrl 确实有一个值。

<Nullable>enable</Nullable>在 csproj 中有,以防万一这会有所作为。

这是 Login.cshtml.cs 和 Login.cshtml 文件内容与脚手架完全相同,并导致了问题。有什么想法可能是错的吗?

// Login.cshtml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using POS.WebAdmin.Data.Model;

namespace POS.WebAdmin.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LoginModel : PageModel
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly SignInManager<ApplicationUser> _signInManager;
        private readonly …
Run Code Online (Sandbox Code Playgroud)

c# authentication .net-core asp.net-core blazor-server-side

8
推荐指数
1
解决办法
4321
查看次数

如何从子组件获取对 Blazor MainLayout 的引用

我将一些全局 Blazor 组件放入 Blazor 服务器端应用程序的 MainLayout 中。它们用于显示警报、确认、警告……

从子组件中,如何获取对 MainLayout 的引用以调用我的全局警报、确认函数?

子组件是动态的,并且可以位于任何嵌套级别中。所以我们不知道从它到根MainLayout有多少层。

这就像Winform应用程序中ApplicationContext.MainForm的概念。

blazor blazor-server-side

8
推荐指数
2
解决办法
3313
查看次数

关闭/断开 ASP.NET Core signalR 客户端连接的正确方法是什么?

我是一名新用户,正在努力从 ASP.NET Core Blazor 服务器页面正常关闭辅助 signalR 客户端。

我正在 Blazor 服务器页面的首次渲染上设置辅助 signalR 客户端连接。当通过浏览器选项卡关闭页面时,我试图关闭此辅助 signalR 客户端连接。

在撰写本文时,DisposeAsync通过浏览器选项卡关闭页面时似乎不会触发。然而,该Dispose方法触发。此外,在 Safari 13.0.5 中,Dispose关闭浏览器选项卡时不会触发该方法?Opera、Firefox 和 Chrome 都Dispose在关闭浏览器选项卡时触发。通过 macOS Catalina v10.15.7 将 Safari 更新至 v14.0(15610.1.28.9、15610)修复了此问题。

目前,我正在调用DisposeAsyncfromDispose以关闭 signalR 连接。我使用以下代码关闭客户端连接:

...
Logger.LogInformation("Closing secondary signalR connection...");
await hubConnection.StopAsync();
Logger.LogInformation("Closed secondary signalR connection");
...
Run Code Online (Sandbox Code Playgroud)

StopAsync方法似乎被阻止,即没有输出“关闭辅助信号R连接”的消息。尽管如此,OnDisconnectedAsync我的服务器集线器的处理程序显示连接已断开。这与本期中描述的行为类似。

如何在ASP.NET Core 3.1中正确处理 signalR 连接?

完整的代码清单如下所示:

处理 signalR 连接

 #region …
Run Code Online (Sandbox Code Playgroud)

signalr signalr.client asp.net-core asp.net-core-signalr blazor-server-side

8
推荐指数
1
解决办法
1万
查看次数

Blazor 的 IDbContextFactory:何时使用 CreateDbContextAsync 异步版本与 CreateDbContext

IDbContextFactory.CreateDbContext我在处理 Blazor 服务器项目时开始使用。我知道此接口是为 Blazor 创建的,旨在解决有状态 Blazor 服务器应用程序中的 DbContext 并发问题。

到目前为止我一直在做

using var context = _contextFactory.CreateDbContext();
//Then use the context...
Run Code Online (Sandbox Code Playgroud)

但我刚刚发现该方法有一个异步版本,IDbContextFactory.CreateDbContextAsync文档只是说“在异步上下文中创建新的 DbContext 实例”。

所以我的问题是我应该更喜欢一个版本而不是另一个版本吗?上下文创建是否是一个昂贵/可能阻塞的操作,需要异步操作?

entity-framework entity-framework-core blazor blazor-server-side

8
推荐指数
1
解决办法
2639
查看次数

授权需要类型为 Task&lt;AuthenticationState&gt; 的级联参数。考虑使用 CascadingAuthenticationState 来提供此

我有一个使用个人帐户设置的 Blazor 服务器端项目。我搭建了 AspNet.Core.Identity 页面,并希望通过使用<component>标签助手在其中一个 razor 页面中使用 Blazor 组件。

我的剃刀页面:

@page
@using SenseNet.Pages
@model WalletModel
@{
    ViewData["Title"] = "Wallet Data";
    ViewData["ActivePage"] = "WalletData";
}
@{
    Layout = "_Layout.cshtml";
}
<h3>@ViewData["Title"]</h3>
<component type="typeof(Counter)" render-mode="ServerPrerendered" />
Run Code Online (Sandbox Code Playgroud)

我的 Counter Blazor 组件:

@page "/counter"

<PageTitle>Counter</PageTitle>
<h1>Counter</h1>

<AuthorizeView Policy="TwoFactorEnabled">
    <h1>Hello, @context.User.Identity.Name!</h1>
    <p>You can only see this content if you're authenticated.</p>
</AuthorizeView>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    private int currentCount …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-core razor-pages blazor-server-side

8
推荐指数
1
解决办法
1万
查看次数