前言这不是和《Task.Factory.StartNew 和 Task.Run 到底有什么区别?》一样吗,怎么又写一篇?起先我也是这么觉得的,但实际发现并非如此。实现代码查看这 2 个方法的内部实现,其内部实现逻辑其实是一样的,只是传的默认参数不同://Task.Factory.StartNew<TResult>public Task<TResult> StartN
前言Task.Factory.StartNew 和 Task.Run 都可以创建 Task:Task.Factory.StartNew(() => { Console.WriteLine("Task.Factory.StartNew"); });Task.Run(() => { Console.WriteLine("Task.Run"); });那它们之间有什么区别呢?实现代码查看这
前言文章名字有点绕口,举例说明一下:多用户使用同一个网站上传文件,但是因为一些原因,文件需要存储到服务器的不同目录下。比如用户 A 对应 c:\abc,用户 B 对应 d:\xyz\123。并且,文件需要以静态文件方式提供访问。由于每个用户的静态文件存储目录不同,这就需要根据用户当前请求动态确定存储目录。怎么实现?思路默认情况下,静态文件存储在项目的 Web 根目录中。默认目录为
前言我们常用 JWT 令牌用于身份验证,前端一般是在请求中包含 HTTP 标头 Authorization 实现。但是,当服务间需要互相调用时,也需要"按原样"将标头传播到目标服务。原来的解决方案是从请求中读取标头,并将其添加到对外请求标头集合中。后来发现,微软已经考虑了这种场景,并提供了专门的中间件来解决这个需求。Demo下面,我们创建 ServerA、ServiceB 两个
前言很荣幸,在愚人节这天?,收到了获得“微软 MVP”奖项的通知:由于该奖项评选标准只涉及 2021 年所做的贡献,而我的贡献主要是公众号文章。因此以我从 2021/06 开始运营个人公众号算起,可以说,仅花了 6 个月,我就成为了“微软 MVP”。什么是微软 MVP?微软最有价值专家奖项(Microsoft Most Valuable Professional--MVP)
原文链接:https://blazor-university.com/layouts/布局Blazor 布局类似于 ASP Webforms 母版页的概念,与 ASP MVC 中的 Razor 布局相同。几乎网络上的每个网站都有一个模板用于整个网站(页面顶部的品牌,底部的版权)或网站的特定子部分(例如站点管理页面上的特定菜单结构)。这是通过创建一个视图来实现的,该视图充当当前页面内容的 HTML
前言在业务开发时,我们常常需要生成有过期时间的 Token 凭证。比如重置密码,即使被其他人获取到链接,超过指定时间也无法操作,以保证安全性:常用的实现方式,可以使用缓存或数据库存储 Token 的过期时间。今天,我们介绍另一种实现方式。IDataProtector.NET Core 中默认提供了一个数据保护组件,可以用来保护我们的数据:首先,需要在 Startup.cs 中配置使用数据保护组件:
前言如果你开发过vue应用,应该对其交互式命令行印象深刻:它允许你无需任何编程经验,仅需回答问题,就可完成vue应用创建。虽然作为.NETer,大部分情况下我们不会使用命令行,但是还是希望能用C#开发出这样的交互式命令行应用,比如代码生成器。Sharprompt介绍Sharprompt是一个基于C#的交互式命令行应用框架,具有如下特点:多平台支持支持常用的提示方式(普通输入/密码/选择项等)支持基
前言假设,我们需要单元测试如下方法:public User GetUser(int id){ return Repository.Query<User>(new { ID = id }).FirstOrDefault();}而对于Repository.Query,我们需要进行Mock。怎么实现?不匹配具体参数值如果我们不关心参数的具体值,可以简单地让它匹配任何object:m
前言某台服务器上的IIS应用程序池,最近经常会自动关闭。查看服务器上的事件日志,发现在关闭时,w3p.exe抛出了stackoverflow异常。幸好,Windows自动帮我们抓取了Crash的dump文件:一般来说,我们会使用windbg来分析dump文件,但是对于这种异常dump,更简单的方法是使用VS 2019。分析方法1.打开dump文件双击memory.hdump,默认应该可以直接打
前言为了性能监控的目的,我们使用了Middleware记录所有请求的Log。实现代码如下:public class RequestLoggingMiddleware{ ... public async Task Invoke(HttpContext context) { try { await _next(context);
前言上次,我们介绍了Pitcher,可以帮我们简化卫语句:public User(string name, int age){ Throw.When(string.IsNullOrWhiteSpace(name), new ArgumentNullException(nameof(name))); Throw.When(age <= 0, new ArgumentOutOfRan
前言在公众号上看到一篇文章《正确使用和理解C#中的闭包》,里面提到了闭包的一个坑:当捕获的外部变量为for循环的迭代变量时,C#认为变量i是定义在循环体外的。所以,当添加委托集合的for循环执行完时,i的值已经变为3了;因此,我们在foreach中循环调用委托时,i的值就都是3了。List<Action> levyActions = new List<Action>();f
前言当我们为Web API编写测试用例时,代码基本是这样的:public class UnitTest1{ private readonly TestServer _server; private readonly HttpClient _client; public UnitTest1() { // Arrange _server = new
GraphQL介绍GraphQL是一个用于API的查询语言,是一个使用基于类型系统来执行查询的服务端运行时。GraphQL对你的API中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余。Hot Chocolate介绍Hot Chocolate是.NET平台下的开源GraphQL服务器,符合最新的GraphQL 2021草案规范。Hot Chocolate消
前言在.NET Core应用中访问ASP.NET Core Web API接口,常用的方式是使用IHttpClientFactory生成HttpClient实例,并通过结合Polly策略,以实现重试,熔断等机制。在本文中,我们将介绍如何使用Refit,结合Polly访问ASP.NET Core Web API。Refit介绍Refit是一个类型安全的REST开源库,可通过Refit更加简单安全地访
前言上次,我们介绍了行为驱动开发(BDD),使用目前主流的SpecFlow框架。它的优点是可以使用纯文本编写测试用例,不需要编程经验。如果测试用例也全部是程序员写的情况,这种方式反而存在障碍,feature使用与编写代码的语言完全不同的语言来编写,维护测试需要在feature和step代码间来回切换。LightBDDLightBDD是轻量级的行为驱动开发框架。它提供了一种替代方案,你可
前言在VS中打开项目属性,选择“生成事件”选项卡。在“生成前事件命令行”或“生成后事件命令行”文本框中可以输入任何命令提示符或.bat文件中有效的命令:但是,有没有可能执行更丰富的命令呢?生成事件的本质上面设置的“生成事件”保存在哪?编辑项目文件,可以看到它实际上是一个MsBuild目标,执行Exec任务:<Target Name="PreBuild" BeforeTarge
google/zxzx是谷歌开源的一个能够帮助开发者快速编写脚本的工具,它使用JavaScript作为编程语言。示例脚本如下:#!/usr/bin/env zxawait $`cat package.json | grep name`let branch = await $`git branch --show-current`await $`dep deploy --branch=${branch
前言最近在公众号上看到一篇文章《究竟是什么可以比反射还快实现动态调用?》,它使用的是Newbe.ObjectVisitor,基于C#表达式树访问一个普通class的所有属性和对应的值,可以拥有比直接使用反射快上10倍的性能。就这一需求来说,我认为Source Generators应该会更快,因为访问代码在编译时而不是运行时就生成了。事实也验证了确实如此:实现这次我们使用第三方开发的
前言防SQL注入,常用的方案是使用Dapper执行SQL的参数化查询。例如:using (IDbConnection conn = CreateConnection()){ string sqlCommandText = @"SELECT * FROM USERS WHERE ID=@ID"; Users user = conn.Query<Users>(sqlComman
前言通常,我们采用数值ID(long)/GUID作为全局唯一标识符。但是,在多线程、高并发情况下,由应用程序生成数值ID容易产生重复,而由数据库生成又会造成性能瓶颈。而使用Guid.NewGuid()生成的GUID虽然不会重复,但是它是无序的,不适合作为数据库主键,会产生大量索引碎片,影响性能。有不有什么方法,能生成既是顺序的,又不会重复的全局唯一标识符?snowflake大家可能首先想到
前言上次,我们介绍了hashids.net,可以将数值型Id加密成无意义的字符串,但是通过这些字符串又可以反向映射出真实的Id以供内部使用。比如B站的播放链接https://www.bilibili.com/video/BV1xK4y1VXXX应该就是这种实现方式。但是,我们希望在ASP.NET Core Web API实现中使用的还是真实的数值型Id,方便操作;而在对外输入/输
什么是卫语句在方法的开头,我们经常会添加一些检查代码,当检查条件为true时立刻从方法中返回。这样的单独检查代码被称为“卫语句”。例如,我们在添加用户时会检查用户名不能为空,年龄必须大于0:public void AddUser(string name, int age){ if (string.IsNullOrWhiteSpace(name)) { thro
前言下面这段代码,你能发现什么问题吗?public static int? Test1(string str){ return str switch { "A" => 1, "B" => 2, "C" => 3, _ => default, };}public static int? Test2(st
前言前段时间,我们已经用Source Generators实现了好多功能,比如AutoMapper、API最佳实践。你看完那些实现代码,是不是还有点云里雾里!Source Generators到底是怎么做到的?基础知识Source Generators是编译过程的一部分,它以编译树作为输入,通过分析代码,动态生成文件并把它们加入到编译过程中:需要注意的是,你只能添加一些东西到代码,但不
问题由于依赖注入,特别是构造函数注入的广泛使用,使得编写单元测试时,需要使用Mock框架(例如Moq)生成测试类的依赖接口的"模拟"实现,并验证接口是否按预期使用。例如eShopOnContainers中的测试代码就使用了Moq,实现如下:private readonly Mock<IMediator> _mediatorMock;private readonly Mo
通常,我们在ASP.NET Core API服务端实现缓存,数据直接从缓存中取出,返回给客户端,以便加快响应速度。但是这样的做法,解决不了数据传输到客户端需要占用带宽带来的性能问题。这时,可以尝试使用ETag。ETag协议ETag是一个字符串;它表示客户端拥有的数据的某个“版本”。客户端需要在请求头If-None-Match中传入ETag值,服务端检查到此特定请求头,会将此值与
在使用EF Core的时候,很多时候需要知道EF Core实际执行的SQL语句是什么。Simple Logging是EF Core提供的一项功能,可用于在开发和调试应用程序时轻松获取日志。这种形式的日志记录需要最少的配置,而不需要其他NuGet包。功能一瞥配置起来非常简单,只需在DbContext.OnConfiguring实现中调用LogTo方法即可:public class
问题为了安全性起见,客户要求客户端必须将数据加密后才能传给服务端。起先,准备使用非对称加密(RSA)方式,但是发现它对原始文本长度有限制。而对称加密(AES)没有长度限制,但是使用固定密钥存在暴露的风险。有没有两全其美的办法呢?思路密钥肯定每个用户不同,而要验证用户则必须登录。因此,唯一可以安全获取密钥的时机,只能是在登录时。而为了保证用户名密码传输安全,可以使用RSA公钥加密后传输,所有
Copyright © 2005-2025 51CTO.COM 版权所有 京ICP证060544号