Blazor入门100天 : 身份验证和授权 (5) - 本地化资源

news2025/7/10 12:50:36

目录

  1. 建立默认带身份验证 Blazor 程序
  2. 角色/组件/特性/过程逻辑
  3. DB 改 Sqlite
  4. 将自定义字段添加到用户表
  5. 脚手架拉取IDS文件,本地化资源
  6. freesql 生成实体类,freesql 管理ids数据表
  7. 初始化 Roles,freesql 外键 => 导航属性
  8. 完善 freesql 和 bb 特性

本节源码

https://github.com/densen2014/Blazor100/tree/Blazor-%E6%95%99%E7%A8%8B15-5/b16blazorIDS2

拉取IDS源码到本地

自定义字段

  1. 自定义字段参考 https://www.cnblogs.com/densen2014/p/17083937.html
  2. 如果没有做上一个步骤,要重新来一遍: 把项目其他的 Identity 也替换为新的 WebAppIdentityUser 类
  3. 如果接着教程弄的,就已经生成完整的代码了.

本地化资源

安利一个小工具 https://github.com/Kerwin1202/VsTranslator

开启自动翻译后, 鼠标停留就自动翻译, 点击翻译语句直接替换原字符串,太解放生产力了!

选几个常用的处理一下

1. 本地化登录页面

文件 Areas\Identity\Pages\Account\Login.cshtml

@page
@model LoginModel

@{
    ViewData["Title"] = "登录";
}

<h1>@ViewData["Title"]</h1>
<div class="row">
    <div class="col-md-4">
        <section>
            <form id="account" method="post">
                <h2>使用本地账号登录.</h2>
                <hr />
                <div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
                <div class="form-floating mb-3">
                    <input asp-for="Input.Email" class="form-control" autocomplete="用户名" aria-required="true" placeholder="name@example.com" />
                    <label asp-for="Input.Email" class="form-label">Email</label>
                    <span asp-validation-for="Input.Email" class="text-danger"></span>
                </div>
                <div class="form-floating mb-3">
                    <input asp-for="Input.Password" class="form-control" autocomplete="当前密码" aria-required="true" placeholder="密码" />
                    <label asp-for="Input.Password" class="form-label">密码</label>
                    <span asp-validation-for="Input.Password" class="text-danger"></span>
                </div>
                <div class="checkbox mb-3">
                    <label asp-for="Input.RememberMe" class="form-label">
                        <input class="form-check-input" asp-for="Input.RememberMe" />
                        @Html.DisplayNameFor(m => m.Input.RememberMe)
                    </label>
                </div>
                <div>
                    <button id="login-submit" type="submit" class="w-100 btn btn-lg btn-primary">登录</button>
                </div>
                <div>
                    <p>
                        <a id="forgot-password" asp-page="./ForgotPassword">忘记密码了吗?</a>
                    </p>
                    <p>
                        <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">注册为新用户</a>
                    </p>
                    <p>
                        <a id="resend-confirmation" asp-page="./ResendEmailConfirmation">重新发送电子邮件确认</a>
                    </p>
                </div>
            </form>
        </section>
    </div>
    <div class="col-md-6 col-md-offset-2">
        <section>
            <h3>使用其他服务登录.</h3>
            <hr />
            @{
                if ((Model.ExternalLogins?.Count ?? 0) == 0)
                {
                    <div>
                        <p>
                            没有配置外部身份验证服务。查看链接 <a href="https://go.microsoft.com/fwlink/?LinkID=532715">文章
                            关于设置此 ASP.NET 应用程序以支持通过外部服务登录</a>.
                        </p>
                    </div>
                }
                else
                {
                    <form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
                        <div>
                            <p>
                                @foreach (var provider in Model.ExternalLogins!)
                                {
                                    <button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="使用您的 @provider.DisplayName 帐户登录">@provider.DisplayName</button>
                                }
                            </p>
                        </div>
                    </form>
                }
            }
        </section>
    </div>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

后置代码 Login.cshtml.cs 里面的 InputModel 也处理一下

    public class InputModel
    {
        /// <summary>
        /// 此 API 支持 ASP.NET Core Identity 默认 UI 基础结构,不打算使用
        /// 直接来自您的代码。此 API 可能会在未来的版本中更改或删除。
        /// </summary>
        [Required]
        [EmailAddress]
        public string Email { get; set; }

        /// <summary>
        /// 此 API 支持 ASP.NET Core Identity 默认 UI 基础结构,不打算使用
        /// 直接来自您的代码。此 API 可能会在未来的版本中更改或删除。
        /// </summary>
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "密码")]
        public string Password { get; set; }

        /// <summary>
        /// 此 API 支持 ASP.NET Core Identity 默认 UI 基础结构,不打算使用
        /// 直接来自您的代码。此 API 可能会在未来的版本中更改或删除。
        /// </summary>
        [Display(Name = "记住账号?")]
        public bool RememberMe { get; set; }
    }

运行截图

2. 本地化注册页面

文件 Areas\Identity\Pages\Account\Register.cshtml

注册密码默认长度有两个地方设置

1.Program.cs 设置

builder.Services.AddDefaultIdentity<WebAppIdentityUser>(o =>
 {   // Password settings.
     o.Password.RequiredLength = 1;
 }
)
  1. Register.cshtml.csInputModel

修改 StringLength 特性, 顺便添加 Display 特性

        [Required]
        [StringLength(100, MinimumLength=1, ErrorMessage = "{0} 的长度必须至少为 {2},最多为 {1} 个字符.")]
        [DataType(DataType.Password)]
        [Display(Name = "密码")]
        public string Password { get; set; }

运行截图

3. 本地化资料页面, 添加全名

文件 Areas\Identity\Pages\Account\Manage\Index.cshtml

添加代码

<div class="form-floating mb-3">
  <input asp-for="Input.Name" class="form-control" placeholder="请输入您的全名." />
  <label asp-for="Input.Name" class="form-label"></label>
  <span asp-validation-for="Input.Name" class="text-danger"></span>
</div>

后置代码文件 Index.cshtml.cs

public string PhoneNumber { get; set; } 后加入代码

    public class InputModel
    {
        ...
        [Display(Name = "名称")]
        public string Name { get; set; }
    }

LoadAsync() 里加入 Name 字段相关代码

    private async Task LoadAsync(WebAppIdentityUser user)
    {
        var userName = await _userManager.GetUserNameAsync(user);
        var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
        var name = user.Name;

        Username = userName;

        Input = new InputModel
        {
            PhoneNumber = phoneNumber,
            Name = name
        };
    }

OnPostAsync() 里加入 Name 字段相关代码

    public async Task<IActionResult> OnPostAsync()
    {
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            return NotFound($"无法加载具有 ID 的用户 '{_userManager.GetUserId(User)}'.");
        }

        if (!ModelState.IsValid)
        {
            await LoadAsync(user);
            return Page();
        }

        var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
        if (Input.PhoneNumber != phoneNumber)
        {
            var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
            if (!setPhoneResult.Succeeded)
            {
                StatusMessage = "尝试设置电话号码时出现意外错误.";
                return RedirectToPage();
            }
        }

        var name = user.Name;
        if (Input.Name != name)
        {
            user.Name = Input.Name;
            await _userManager.UpdateAsync(user);
        }

        await _signInManager.RefreshSignInAsync(user);
        StatusMessage = "你的个人资料已经更新";
        return RedirectToPage();
    }

运行截图

本节源码

https://github.com/densen2014/Blazor100/tree/Blazor-%E6%95%99%E7%A8%8B15-5/b16blazorIDS2

源代码

https://github.com/densen2014/Blazor100

https://gitee.com/densen2014/Blazor100 (镜像/非最新版)—

关联项目

FreeSql QQ群:4336577

BA & Blazor QQ群:795206915

Maui Blazor 中文社区 QQ群:645660665

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow,不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系 。

转载声明

本文来自博客园,作者:周创琳 AlexChow,转载请注明原文链接.

AlexChow

今日头条 | 博客园 | 知乎 | Gitee | GitHub

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/362672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FreeRTOS入门(01):基础说明与使用演示

文章目录目的基础说明系统移植基础使用演示数据类型和命名风格总结碎碎念目的 FreeRTOS是一个现在非常流行的实时操作系统&#xff08;Real Time Operating System&#xff09;。本文将介绍FreeRTOS入门使用相关内容&#xff0c;这篇是第一篇&#xff0c;主要介绍基础背景方面…

追梦之旅【数据结构篇】——详解C语言动态实现带头结点的双向循环链表结构

详解C语言动态实现带头结点的双向循环链表结构~&#x1f60e;前言&#x1f64c;预备小知识&#x1f49e;链表的概念及结构&#x1f64c;预备小知识&#x1f49e;链表的概念及结构&#x1f64c;带头结点的双向循环链表结构&#x1f64c;整体实现内容分析&#x1f49e;1.头文件编…

openpose在win下环境配置

1.下载OpenPose库 以下二选一进行下载源码 (1)git进行下载 打开GitHub Desktop或者Powershell git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose cd openpose/ git submodule update --init --recursive --remote(2)在github上手动下载 由于下载环境问…

SpringCloud Alibaba 之Nacos集群部署-高可用保证

文章目录Nacos集群部署Linux部署docker部署&#xff08;参考待验证&#xff09;Nacos 集群的工作原理Nacos 集群中 Leader 节点是如何产生的Nacos 节点间的数据同步过程官方推荐用户把所有服务列表放到一个vip下面&#xff0c;然后挂到一个域名下面。http://nacos.com:port/ope…

go进阶(1) -深入理解goroutine并发运行机制

并发指的是同时进行多个任务的程序&#xff0c;Web处理请求&#xff0c;读写处理操作&#xff0c;I/O操作都可以充分利用并发增长处理速度&#xff0c;随着网络的普及&#xff0c;并发操作逐渐不可或缺 一、goroutine简述 在Golang中一个goroutines就是一个执行单元&#xff…

活动报名丨亚马逊科学家杨靖锋:复现和使用GPT3/ChatGPT的想法

2023年2月23日&#xff08;星期四&#xff09;11:00-12:00&#xff0c;由智源社区主办的「智源LIVE 第30期丨亚马逊科学家杨靖锋讲解『一些关于复现和使用GPT3/ChatGPT的想法』将在线举办&#xff0c;敬请期待。杨靖锋杨靖锋是来自亚马逊的科学家。他的研究主要集中在自然语言处…

ESP32设备驱动-深度休眠与唤醒

深度休眠与唤醒 文章目录 深度休眠与唤醒1、ESP32的休眠模式介绍1.1 ESP32的休眠模式1.2 RTC_GPIO1.3 唤醒源1.4 唤醒流程2、软件准备3、硬件准备4、定时器唤醒5、触摸唤醒6、外部中断唤醒6.1 外部中断ext0唤醒6.2 外部中断ext1唤醒6.3 多GPIO唤醒本文将详细在Arduino IDE中如何…

Spring MVC常用功能及注解

目录 一、什么是Spring MVC 1.1 Spring MVC定义 1.2 MVC定义 1.3 MVC和Spring MVC的关系 1.4 Spring MVC的作用 二、Spring MVC的使用 2.1 Spring MVC的创建和连接 2.1.1 RequestMapping注解 2.1.2 GetMapping注解 2.1.3 PostMapping注解 2.2 获取参数 2.2.1 获取单…

unbound部署DNS

dns的主要作用是将域名解析为ip地址然后在进行访问 安装配置dns准备3台服务器&#xff08;地址都要设置为静态的以便自己配置dns&#xff09;192.168.92.1 用户ip地址&#xff08;windows&#xff09; 192.168.92.132 dns服务器地址 192.168.92.133 web服务器地址 dns服务器 …

网络编程之TCP 网络应用程序开发流程

TCP 网络应用程序开发流程学习目标能够知道TCP客户端程序的开发流程1. TCP 网络应用程序开发流程的介绍TCP 网络应用程序开发分为:TCP 客户端程序开发TCP 服务端程序开发说明:客户端程序是指运行在用户设备上的程序 服务端程序是指运行在服务器设备上的程序&#xff0c;专门为客…

【沐风老师】3DMAX橱柜生成器工具使用教程

3DMAX橱柜生成器工具使用教程 【生成的橱柜模型】 3DMAX橱柜生成器&#xff08;Kitchen Cabinet Creator&#xff09;用于在3ds Max中自动制作橱柜模型。是需要频繁设计厨房、家具和室内设计的用户的理想工具插件&#xff0c;也是所有希望通过点击几下鼠标来填充一些空白空间的…

游戏服务器算法-AOI九宫格python实现

将空间按照一定的方法进行分割&#xff0c;例如根据AOI范围的大小将整个游戏世界切分为固定大小的格子。当游戏物体位于场景的时候&#xff0c;根据坐标将它放入特定的格子中。 例如玩家1在位置7中&#xff0c;如果游戏内的AOI的范围为1个格子。当我们需要获取这个玩家周围的AO…

第九章 - 多表查询(join,left join 等),合并查询(union union all),子查询

第九章 - 多表查询&#xff08;join&#xff0c;left join 等&#xff09;&#xff0c;合并查询&#xff08;union & union all&#xff09;&#xff0c;子查询交叉链接&#xff08;笛卡尔积&#xff09;内连接查询外连接查询左链接&#xff1a; left join右链接&#xff1…

python3遍历目录的三种方法浅谈

日期&#xff1a;2023年2月22日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

JavaScript中怎么实现链表?

JavaScript中怎么实现链表&#xff1f; 学习数据结构的的链表和树时&#xff0c;会遇到节点&#xff08;node&#xff09;这个词&#xff0c;节点是处理数据结构的链表和树的基础。节点是一种数据元素&#xff0c;包括两个部分&#xff1a;一个是实际需要用到的数据&#xff1b…

MATLAB | 如何用MATLAB绘制这样有气泡感的网络图

今天给大家带来一款用来绘制有气泡感的网络图的工具函数&#xff0c;绘制效果如下&#xff1a; 花里胡哨的&#xff0c;气泡大小代表流入流出数据量综合&#xff0c;不同颜色的气泡代表属于不同类&#xff0c;两个气泡之间有连线代表有数据流动&#xff0c;连线透明度代表流动数…

木鱼cms 审计小结

MuYuCMS基于Thinkphp开发的一套轻量级开源内容管理系统,专注为公司企业、个人站长提供快速建站提供解决方案。‍环境搭建我们利用 phpstudy 来搭建环境&#xff0c;选择 Apache2.4.39 MySQL5.7.26 php5.6.9 &#xff0c;同时利用 PhpStorm 来实现对项目的调试‍漏洞复现分析‍…

经过深思熟虑后的接口测试自动化的总结与思考

序近期看到阿里云性能测试 PTS 接口测试开启免费公测&#xff0c;本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接口测试领域的一些方法和心得&#xff0c;希望大家一起讨论和分享&#xff0c;内容包括但不仅限于&#xff1a;服务端接口测试介绍接…

中央一号文件首提“即时零售”,县域掀起消费业态新风潮

经过几年的探索&#xff0c;即时零售已经逐步走向成熟&#xff0c;并开始向三四线城市以及乡镇城市渗透。 过去一年&#xff0c;京东、美团、阿里争先布局即时零售市场&#xff0c;完善即时配送网络、培养用户消费习惯&#xff0c;即时零售订单迎来了骤增。2022年下半年&#…

【字节面试】Fail-fast知识点相关知识点

字节面试&#xff0c;问到的一个小知识点&#xff0c;这里做一下总结&#xff0c;其实小编之前有一篇文章&#xff0c;已经对此有过涉及&#xff0c;不过这里知识专项针对于问题&#xff0c;把这个知识点拎出来说一下。 1.问题 什么是Fail-fast机制&#xff1f; Hashmap是否拥…