文章目录

  • 前言
  • 一、JWT与RBAC
  • 二、JWT 的作用
  • 三、RBAC 的核心思想
  • 四、使用
    • 1、配置文件 (appsettings.json)
    • 2、JWT配置模型 (Entity/JwtSettings.cs)
    • 3、服务扩展类,JWT配置 (Extensions/ServiceExtensions.cs)
    • 4、用户仓库接口服务
    • 5、认证服务 (Interface/IAuthService.cs、Repository/AuthService.cs)
    • 6、控制器(验证登录权限,生成Token)
    • 7、注册服务
    • 8、使用示例
    • 9、高级权限控制
      • 1)实现自定义策略处理器:
      • 2)注册服务及定义策略
      • 3)使用自定义策略
  • 五、关键安全配置
  • 六、完整流程说明
  • 总结


前言

ASP.NET Core Web API中实现基于JWTRBAC(基于角色的访问控制)。

一、JWT与RBAC

JWT(JSON Web Token)与 RBAC(基于角色的访问控制,Role-Based Access Access Control)结合使用时,是一种通过令牌(Token)传递用户角色信息,并基于角色实现权限管理的安全机制。

二、JWT 的作用

  • JWT 是一种紧凑的、自包含的令牌格式,通常用于身份验证和授权。其结构分为三部分:
    • Header:算法和令牌类型(如 HS256RSA)。
    • Payload:存放用户信息(如用户ID、角色)和声明(如过期时间)。
    • Signature:对前两部分的签名,确保令牌未被篡改。

三、RBAC 的核心思想

  • RBAC 通过角色管理权限,而非直接赋予用户权限:
    • 角色(Role):定义一组权限(如 adminuser)。
    • 权限(Permission):资源或操作(如 read:data、delete:user)。
    • 用户被分配角色,间接获得权限。

四、使用

1、配置文件 (appsettings.json)

  1. appsettings.json
    {"JwtSettings": {"Issuer": "yourdomain.com","Audience": "yourapp","SecretKey": "YourSuperSecretKeyAtLeast32CharactersLong","ExpirationMinutes": 60,"RefreshTokenExpirationDays": 7}"AllowedHosts": "*"
    }
    

2、JWT配置模型 (Entity/JwtSettings.cs)

  1. JwtSettings.cs
    namespace JWTWebAPI.Entity
    {public class JwtSettings{public string Issuer { get; set; } = string.Empty;public string Audience { get; set; } = string.Empty;public string SecretKey { get; set; } = string.Empty;public int ExpirationMinutes { get; set; }public int RefreshTokenExpirationDays { get; set; }}
    }
    

3、服务扩展类,JWT配置 (Extensions/ServiceExtensions.cs)

  1. ServiceExtensions.cs
    using JWTWebAPI.Entity;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.IdentityModel.Tokens;
    using System.Security.Claims;
    using System.Text;namespace JWTWebAPI.Extensions
    {public static class ServiceExtensions{// JWT认证配置public static void ConfigureJwtAuthentication(this IServiceCollection services, IConfiguration configuration){var jwtSettings = configuration.GetSection("JwtSettings").Get<JwtSettings>();services.AddAuthentication(options =>{options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(options =>{options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = false,ValidIssuer = jwtSettings.Issuer,ValidateAudience = false,ValidAudience = jwtSettings.Audience,ValidateLifetime = false,ValidateIssuerSigningKey = false,IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey!)), //ClockSkew = TimeSpan.Zero,RoleClaimType=ClaimTypes.Role};options.Events = new JwtBearerEvents{OnAuthenticationFailed = context =>{if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)){context.Response.Headers.Append("Token-Expired", "true");}return Task.CompletedTask;}};});}// 授权策略配置public static void ConfigureAuthorizationPolicies(this IServiceCollection services){services.AddAuthorization(options =>{// 基于角色的策略options.AddPolicy("AdminOnly", policy =>policy.RequireRole("admin"));options.AddPolicy("ManagerOnly", policy =>policy.RequireRole("admin"));// 基于自定义权限的策略options.AddPolicy("ContentEditor", policy =>policy.RequireClaim("permission", "content.edit"));options.AddPolicy("UserManagement", policy =>policy.RequireClaim("permission", "user.manage"));});}} 
    }

4、用户仓库接口服务

  1. Interfaces/IUserRepository.cs

    using JWTWebAPI.Entity;namespace JWTWebAPI.Interface
    {public interface IUserRepository{Task<AspNetUsers?> GetUserByCredentials(string username, string password);Task SaveRefreshToken(long userId, string refreshToken, DateTime expiry);Task<AspNetUsers?> GetUserByRefreshToken(string refreshToken);}
    }
  2. Repositories/UserRepository.cs

    using JWTWebAPI.Data;
    using JWTWebAPI.Entity;
    using JWTWebAPI.Interface;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;
    using Org.BouncyCastle.Crypto.Generators;namespace JWTWebAPI.Repository
    {public class UserRepositor : IUserRepository{private readonly MyDbContext _context;private readonly UserManager<AspNetUsers> _userManager;public UserRepositor(MyDbContext context, UserManager<AspNetUsers> userManager, RoleManager<Role> roleManager){_context = context;_userManager = userManager;}public async Task<AspNetUsers?> GetUserByCredentials(string username, string password){try{var user=await _userManager.FindByNameAsync(username);if (user == null) return null;return user;}catch (Exception){throw;}}public async Task<AspNetUsers?> GetUserByRefreshToken(string refreshToken){return await _context.Users.FirstOrDefaultAsync(u =>u.RefreshToken == refreshToken &&u.RefreshTokenExpiry > DateTime.UtcNow);}public async Task SaveRefreshToken(long userId, string refreshToken, DateTime expiry){var user = await _context.Users.FindAsync(userId);if (user != null){user.RefreshToken = refreshToken;user.RefreshTokenExpiry = expiry;await _context.SaveChangesAsync();}}}
    }
    

5、认证服务 (Interface/IAuthService.cs、Repository/AuthService.cs)

  1. IAuthService.cs

    using JWTWebAPI.Entity;namespace JWTWebAPI.Interface
    {public interface IAuthService{Task<AuthResult> Authenticate(string username, string password);Task<AuthResult> RefreshToken(string token, string refreshToken);}
    }
    
  2. AuthService.cs

    using JWTWebAPI.Entity;
    using JWTWebAPI.Interface;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Security.Cryptography;
    using System.Text;namespace JWTWebAPI.Repository
    {public class AuthService : IAuthService{private readonly JwtSettings _jwtSettings;private readonly IUserRepository _userRepository;public AuthService(IOptions<JwtSettings> jwtSettings, IUserRepository userRepository){_jwtSettings = jwtSettings.Value;_userRepository = userRepository;}public async Task<AuthResult> Authenticate(string username, string password){var user = await _userRepository.GetUserByCredentials(username, password);if (user == null) return null;var claims = new[]{new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),new Claim(ClaimTypes.Name, user.UserName),new Claim(ClaimTypes.Role, user.Role) // 用户角色	                };var token = GenerateJwtToken(claims);var refreshToken = GenerateRefreshToken();await _userRepository.SaveRefreshToken(user.Id, refreshToken,DateTime.UtcNow.AddDays(_jwtSettings.RefreshTokenExpirationDays));return new AuthResult{Token = token,RefreshToken = refreshToken,ExpiresIn = _jwtSettings.ExpirationMinutes * 60};}public Task<AuthResult> RefreshToken(string token, string refreshToken){throw new NotImplementedException();}private string GenerateJwtToken(IEnumerable<Claim> claims){var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);var token = new JwtSecurityToken(issuer: _jwtSettings.Issuer,audience: _jwtSettings.Audience,claims: claims,expires: DateTime.UtcNow.AddMinutes(_jwtSettings.ExpirationMinutes),signingCredentials: creds);return new JwtSecurityTokenHandler().WriteToken(token);}private static string GenerateRefreshToken(){var randomNumber = new byte[32];using var rng = RandomNumberGenerator.Create();rng.GetBytes(randomNumber);return Convert.ToBase64String(randomNumber);}}
    }
  3. AuthResult.cs

    namespace JWTWebAPI.Entity
    {public class AuthResult{public string Token { get; set; }public string RefreshToken { get; set; }public int ExpiresIn { get; set; }}
    }

6、控制器(验证登录权限,生成Token)

  1. AuthController.cs
    using JWTWebAPI.Entity;
    using JWTWebAPI.Interface;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Identity.Data;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    using System.IdentityModel.Tokens.Jwt;
    using System.Runtime;
    using System.Security.Claims;
    using System.Text;namespace JWTWebAPI.Controllers
    {[Route("api/[controller]/[action]")][ApiController]public class AuthController : ControllerBase{private readonly IConfiguration _config;private readonly IOptionsSnapshot<JwtSettings> _settings;private readonly IAuthService _authService;public AuthController(IConfiguration config, IOptionsSnapshot<JwtSettings> settings, IAuthService authService){_config = config;_settings = settings;_authService = authService;}[HttpPost][AllowAnonymous]public async Task<IActionResult> Login([FromBody] LoginModel request){var result = await _authService.Authenticate(request.Username, request.Password);if (result == null) return Unauthorized();return Ok(result);}[HttpPost][AllowAnonymous]public async Task<IActionResult> Refresh([FromBody] RefreshTokenRequest request){var result = await _authService.RefreshToken(request.Token, request.RefreshToken);if (result == null) return Unauthorized();return Ok(result);}}
    } 
    
  2. LoginModel.cs
    namespace JWTWebAPI.Entity
    {public class LoginModel{public string Username { get; set; } = string.Empty;public string Password { get; set; } = string.Empty;}
    }
    
  3. RefreshTokenRequest.cs
    public class RefreshTokenRequest
    {[Required] public string Token { get; set; }[Required] public string RefreshToken { get; set; }
    }
    

7、注册服务

  1. Program.cs

    using JWTWebAPI.Data;
    using JWTWebAPI.Entity;
    using JWTWebAPI.Extensions;
    using JWTWebAPI.Interface;
    using JWTWebAPI.Repository;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;var builder = WebApplication.CreateBuilder(args);
    // 添加数据库上下文
    var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
    builder.Services.AddDbContext<MyDbContext>(opt => {opt.UseSqlServer(connectionString);
    });
    builder.Services.AddDataProtection();
    builder.Services.AddIdentityCore<AspNetUsers>(opt => {
    opt.Lockout.MaxFailedAccessAttempts = 5;//登录失败多少次账号被锁定
    opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(1);//锁定多长时间
    opt.Password.RequireDigit = false;//密码是否需要数字    
    opt.Password.RequireLowercase = false;//密码是否需要小写字符
    opt.Password.RequireUppercase = false;//密码是否需要大写字符
    opt.Password.RequireNonAlphanumeric = false;//密码是否需要非字母数字的字符
    opt.Password.RequiredLength = 6;//密码长度opt.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;//密码重置令牌,使用默认的邮箱令牌提供程序来生成和验证令牌。此提供程序通常与用户邮箱关联,生成的令牌会通过邮件发送给用户,保证用户通过邮件接收密码重置链接。
    opt.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;//配置邮箱确认令牌(Email Confirmation Token)的生成和验证所使用的提供程序(Provider)
    });
    var idBuilder = new IdentityBuilder(typeof(AspNetUsers), typeof(Role), builder.Services);idBuilder.AddEntityFrameworkStores<MyDbContext>()
    .AddDefaultTokenProviders().AddUserManager<UserManager<AspNetUsers>>()
    .AddRoleManager<RoleManager<Role>>();builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));
    // 添加JWT认证
    // 3. 认证服务配置(来自ServiceExtensions)
    builder.Services.ConfigureJwtAuthentication(builder.Configuration);  // 扩展方法ServiceExtensions.cs
    // 4. 授权策略配置(来自ServiceExtensions)
    builder.Services.ConfigureAuthorizationPolicies();  // 扩展方法ServiceExtensions.cs// 5. 注册应用服务
    builder.Services.AddScoped<IUserRepository, UserRepositor>();
    builder.Services.AddScoped<IAuthService, AuthService>();builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    //跨域
    builder.Services.AddCors(options =>
    {options.AddPolicy("AllowAll", builder =>builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    });var app = builder.Build();// Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {app.UseSwagger();app.UseSwaggerUI();
    }app.UseHttpsRedirection();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseCors("AllowAll");
    app.MapControllers();app.Run();

8、使用示例

  1. AdminController.cs
    在需要权限的Controller上添加特性:
    using JWTWebAPI.Entity;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;namespace JWTWebAPI.Controllers
    {[Route("api/[controller]/[action]")][ApiController]public class AdminController : ControllerBase{[HttpGet][Authorize(Roles = "admin")] // 仅Admin角色可访问public IActionResult GetAdminData(){return Ok("Admin data");}[HttpGet][Authorize(Policy = "AdminOnly")] // 使用策略public IActionResult GetUserInfo(){return Ok("User info");}}
    }
    

9、高级权限控制

1)实现自定义策略处理器:

  1. PermissionHandler.cs

    using JWTWebAPI.Entity;
    using Microsoft.AspNetCore.Authorization;namespace JWTWebAPI.Extensions
    {public class PermissionHandler : AuthorizationHandler<PermissionRequirement>{protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement){var permissions = context.User.FindFirst(c => c.Type == "permissions")?.Value.Split(',');if (permissions?.Any(p => p == requirement.Permission) == true){context.Succeed(requirement);}return Task.CompletedTask;}}
    }
    
  2. PermissionRequirement.cs

    using Microsoft.AspNetCore.Authorization;namespace JWTWebAPI.Entity
    {public class PermissionRequirement: IAuthorizationRequirement{public string Permission { get; set; }public PermissionRequirement(string permission){Permission = permission;}}
    }
    

2)注册服务及定义策略

  1. Program.cs
    //注册
    builder.Services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
    //定义策略(可放在扩展方法中:ServiceExtensions.cs中的ConfigureAuthorizationPolicies方法中)
    builder.Services.AddAuthorization(options =>
    {options.AddPolicy("UpdateValidate", policy =>policy.Requirements.Add(new PermissionRequirement("profile.update")));
    });
    

3)使用自定义策略

  1. AdminController.cs
    using JWTWebAPI.Entity;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;namespace JWTWebAPI.Controllers
    {[Route("api/[controller]/[action]")][ApiController]public class AdminController : ControllerBase{[HttpGet][Authorize(Policy = "UpdateValidate")]public IActionResult GetMessage(){return Ok("自定义验证");}}
    }

五、关键安全配置

  • 密钥安全
    • 生产环境不要将密钥放在appsettings.json
    • 使用Azure Key Vault环境变量存储密钥
    builder.Configuration.AddEnvironmentVariables();
    
  • HTTPS重定向
    app.UseHttpsRedirection();
    
  • CORS配置
    services.AddCors(options =>
    {options.AddPolicy("ApiPolicy", builder =>{builder.WithOrigins("https://your-frontend.com").AllowAnyHeader().AllowAnyMethod().AllowCredentials();});
    });
    

六、完整流程说明

  1. 用户通过/api/auth/login获取JWT Token
  2. 后续请求在Header中添加Authorization: Bearer {token}
  3. 系统自动验证Token有效性
  4. 根据Controller/Action上的授权策略进行权限验证

总结

通过以上实现,可以构建灵活、可扩展的权限控制系统,满足以下场景:

  • 基于资源的细粒度控制
  • 动态权限管理
  • 多条件组合授权

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(19)java在区块链中的应用

&#x1f517; Java在区块链中的应用&#xff1a;智能合约开发全攻略 TL;DR: Java在区块链领域主要通过Hyperledger Fabric、Web3j和专用JVM实现智能合约开发&#xff0c;相比Solidity具有更强的企业级支持和开发效率&#xff0c;但在执行效率和Gas消耗方面存在差异&#xff0c…

深入理解设计模式之访问者模式

深入理解设计模式之访问者模式&#xff08;Visitor Pattern&#xff09; 一、什么是访问者模式&#xff1f; 访问者模式&#xff08;Visitor Pattern&#xff09;是一种行为型设计模式。它的主要作用是将数据结构与数据操作分离&#xff0c;使得在不改变数据结构的前提下&…

div或button一些好看实用的 CSS 样式示例

1&#xff1a;现代渐变按钮 .count {width: 800px;background: linear-gradient(135deg, #72EDF2 0%, #5151E5 100%);padding: 12px 24px;border-radius: 10px;box-shadow: 0 4px 15px rgba(81, 81, 229, 0.3);color: white;font-weight: bold;border: none;cursor: pointer;t…

【基于STM32的新能源汽车智能循迹系统开发全解析】

基于STM32的新能源汽车智能循迹系统开发全解析&#xff08;附完整工程代码&#xff09; 作者声明 作者&#xff1a; 某新能源车企资深嵌入式工程师&#xff08;专家认证&#xff09; 技术方向&#xff1a; 智能驾驶底层控制 | 车规级嵌入式开发 原创声明&#xff1a; 本文已申…

HTML Day02

Day02 0. 引言1. 文本格式化1.1 HTML文本格式化标签1.2 HTML"计算机输出"标签1.3 HTML 引文&#xff0c;引用及标签定义 2. HTML链接2.1链接跳转原理&#xff08;有点乱可跳过&#xff09;2.2 HTML超链接2.3 target属性2.4 id属性2.4.1 id属性在页面内和不同页面的定…

MIT 6.S081 2020 Lab6 Copy-on-Write Fork for xv6 个人全流程

文章目录 零、写在前面一、Implement copy-on write1.1 说明1.2 实现1.2.1 延迟复制与释放1.2.2 写时复制 零、写在前面 可以阅读下 《xv6 book》 的第五章中断和设备驱动。 问题 在 xv6 中&#xff0c;fork() 系统调用会将父进程的整个用户空间内存复制到子进程中。**如果父…

xhr、fetch和axios

XMLHttpRequest (XHR) XMLHttpRequest 是最早用于在浏览器中进行异步网络请求的 API。它允许网页在不刷新整个页面的情况下与服务器交换数据。 // 创建 XHR 对象 const xhr new XMLHttpRequest();// 初始化请求 xhr.open(GET, https://api.example.com/data, true);// 设置请…

电脑驱动程序更新工具, 3DP Chip 中文绿色版,一键更新驱动!

介绍 3DP Chip 是一款免费的驱动程序更新工具&#xff0c;可以帮助用户快速、方便地识别和更新计算机硬件驱动程序。 驱动程序更新工具下载 https://pan.quark.cn/s/98895d47f57c 软件截图 软件特点 简单易用&#xff1a;用户界面简洁明了&#xff0c;操作方便&#xff0c;…

机器学习与深度学习06-决策树02

目录 前文回顾5.决策树中的熵和信息增益6.什么是基尼不纯度7.决策树与回归问题8.随机森林是什么 前文回顾 上一篇文章地址&#xff1a;链接 5.决策树中的熵和信息增益 熵和信息增益是在决策树中用于特征选择的重要概念&#xff0c;它们帮助选择最佳特征进行划分。 熵&#…

【Kotlin】数字字符串数组集合

【Kotlin】简介&变量&类&接口 【Kotlin】数字&字符串&数组&集合 文章目录 Kotlin_数字&字符串&数组&集合数字字面常量显式转换数值类型转换背后发生了什么 运算字符串字符串模板字符串判等修饰符数组集合通过序列提高效率惰性求值序列的操…

oscp练习PG Monster靶机复现

端口扫描 nmap -A -p- -T4 -Pn 192.168.134.180 PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.41 ((Win64) OpenSSL/1.1.1c PHP/7.3.10) |_http-server-header: Apache/2.4.41 (Win64) OpenSSL/1.1.1c PHP/7.3.10 | http-methods:…

近期知识库开发过程中遇到的一些问题

我们正在使用Rust开发一个知识库系统&#xff0c;遇到了一些问题&#xff0c;在此记录备忘。 错误&#xff1a;Unable to make method calls because underlying connection is closed 场景&#xff1a;在docker中调用headless_chrome时出错 原因&#xff1a;为减小镜像大小&am…

Ubuntu 22.04 系统下 Docker 安装与配置全指南

Ubuntu 22.04 系统下 Docker 安装与配置全指南 一、前言 Docker 作为现代开发中不可或缺的容器化工具&#xff0c;能极大提升应用部署和环境管理的效率。本文将详细介绍在 Ubuntu 22.04 系统上安装与配置 Docker 的完整流程&#xff0c;包括环境准备、安装步骤、权限配置及镜…

C#获取磁盘容量:代码实现与应用场景解析

C#获取磁盘容量&#xff1a;代码实现与应用场景解析 在软件开发过程中&#xff0c;尤其是涉及文件存储、数据备份等功能时&#xff0c;获取磁盘容量信息是常见的需求。通过获取磁盘的可用空间和总大小&#xff0c;程序可以更好地进行资源管理、预警提示等操作。在 C# 语言中&a…

2025年- H56-Lc164--200.岛屿数量(图论,深搜)--Java版

1.题目描述 2.思路 &#xff08;1&#xff09;主函数&#xff0c;存储图结构 &#xff08;2&#xff09;主函数&#xff0c;visit数组表示已访问过的元素 &#xff08;3&#xff09;辅助函数&#xff0c;用递归&#xff08;深搜&#xff09;&#xff0c;遍历以已访问过的元素&…

详细到用手撕transformer下半部分

之前我们讨论了如何实现 Transformer 的核心多头注意力机制&#xff0c;那么这期我们来完整地实现整个 Transformer 的编码器和解码器。 Transformer 架构最初由 Vaswani 等人在 2017 年的论文《Attention Is All You Need》中提出&#xff0c;专为序列到序列&#xff08;seq2s…

WPF事件处理器+x名称空间

目录 ​编辑 一、事件处理器知识点 1. XAML中的事件绑定 2. C#中的事件处理方法 3. 方法签名解释 4. 命名规范 工作流程 二、导入引用名称空间 三、x名称空间及其常用元素 &#xff08;1&#xff09;x名称空间的由来和作用 &#xff08;2&#xff09;x名称空间里都有…

Axure设计案例——科技感渐变线性图

想让数据变化趋势展示告别枯燥乏味&#xff0c;成为吸引观众目光的亮点吗&#xff1f;快来看看这个Axure设计的科技感渐变线性图案例&#xff01;科技感设计风格凭借炫酷的渐变色彩打破传统线性图的单调&#xff0c;营造出一种令人过目难忘的视觉体验。每一条线条都仿佛是流动的…

Git全流程操作指南

Git全流程操作指南 一、Git 环境配置 1. 安装 Git Windows&#xff1a;下载 Git for Windows macOS&#xff1a;brew install git Linux&#xff1a; sudo apt-get update && sudo apt-get install git # Debian/Ubuntu sudo yum install git …

AI与软件工程结合的未来三年发展路径分析

基于对数字化、制造业、工业、零售业等行业的系统调研&#xff0c;以及微软、谷歌、阿里、华为等大厂的实践案例&#xff0c;我们可以预见未来三年AI与软件工程结合将呈现以下发展路径和趋势。 一、技术应用维度 1. AI辅助编程工具全面普及 未来三年&#xff0c;AI辅助编程工…