Anduin Xue
Anduin Xue

Anduin's Tech Blog

All Posts


Scan all accessible class in C#

在本篇博客中,我们探讨了如何在C#中获取所有可访问的类。虽然通过调用`GetReferencedAssemblies`方法可以轻松获取到所有引用的程序集,但项目引用是递归的。为了获取所有的类,我们需要构建一个引用树并从整个树中读取。 博客提供了一个名为`ScanAssemblies`的方法,该方法接收一个`Assembly`类型的参数,并返回一个包含所有引用程序集的可枚举集合。通过遍历引用的程序集并递归调用`ScanAssemblies`方法,我们可以构建出完整的引用树。 为了获取所有可访问的类,我们需要加载这些程序集。博客给出了一个名为`AllAccessiableClass`的方法,它首先获取入口程序集,然后调用`ScanAssemblies`方法并对返回的程序集集合进行去重。最后,通过`SelectMany`方法获取每个程序集中的类型并将其添加到一个列表中。 在阅读这篇博客后,你将了解如何在C#中获取所有可访问的类并构建引用树。但在实际应用中,还有哪些场景需要获取所有可访问的类呢?如何优化这个过程以提高性能?希望这篇博客能为你提供一些启示,并引导你自己寻找答案。--GPT 4

C# .NET Core Reflection

Use IIS or Azure App Service as a reverse proxy

In this blog post, we explore the process of setting up a reverse proxy using IIS or Azure App Service. Reverse proxies are beneficial for hiding the origin server's identity and improving performance, security, and load balancing. Before configuring the reverse proxy, it's essential to install IIS and the necessary extensions, such as RequestRouter and Rewrite. Once installed, enable the proxy settings in the IIS management tools and create a new reverse proxy rule by configuring domain bindings and HTTPS certificates. Creating a web.config file under the site root path is crucial for adding rules, such as redirecting HTTP traffic to HTTPS and setting up the real reverse proxy logic. The blog post provides a detailed example of setting up a reverse proxy for Aiursoft.IO and a simpler example for Google.com. To further enhance security, the HSTS feature can be enabled by adding specific code to the web.config file. For deploying the reverse proxy server to Azure App Service, simply ...--GPT 4

IIS web.config Reverse Proxy Web Azure App Service Azure

Share view component between different ASP.NET Core web project

在本篇博客中,我们将探讨如何在不同的ASP.NET Core Web项目之间共享视图组件。当C#中的某些逻辑可以在多个项目之间共享时,我们通常会创建一个新的类库项目。但有时我们只想共享一些视图组件,例如,在`Aiursoft`的所有页面中,它们都包含一个`Logout`组件。多次编写这个组件显然是没有意义的。那么我们如何共享它呢? 首先,我们需要创建一个新的`.NET Core`类库项目,并将其命名为`Aiursoft.Pylon`。接下来,确保你的共享类库支持Razor。修改`csproj`文件以添加属性: <AddRazorSupportForMvc>true</AddRazorSupportForMvc> 现在,你的`Aiursoft.Pylon`项目已经支持编写Razor类库了。我们可以开始编写一个新的视图组件。将所有视图组件放在`Views/Shared/Components`文件夹下。要编写视图组件,请参考以下文档: [https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components) 完成视图组件编写后,你的文件夹应如下所示: ![](/image/img-22d1ae24-0e8c-4abd-b970-214b6fe25b45.png) 现在你的视图组件已经完成,可以在多个项目之间共享了。接下来,创建一个引用你的类库的新Web项目。 ![](/image/img-5f7db548-fe96-43da-962d-016ec2904d62.png) 现在我们将从类库中导入所有视图组件到新的Web项目。修改`_ViewImports.cshtml`以添加类似如下的命名空间: ![](/image/img-1cf766d4-bdb7-4f73-bf12-03732a5c7286.png) 现在你可以在视图中使用共享的视图组件了。如下所示: ![](/image/img-64ede323-6c78-4d7f-833c-cca2bcd60228.png) 如果你的代码以深绿色显示,那么一切正常,你的视图组件可以成...--GPT 4

ASP.NET Core C# class library View component

One command to pull all git repositories

在这篇博客中,我们将探讨如何用一条简单的命令来更新所有的git仓库。如果你的文件夹结构类似于文章中所示,那么这个方法将非常适用。首先,在工作空间文件夹下创建一个名为`pull.sh`的新文件,并将文章中的代码复制到文件中。接下来,执行一个命令以允许运行该脚本。完成这些操作后,每次启动计算机时,只需运行`./pull.sh`,所有仓库便会自动更新。 这个方法不仅节省了时间,还让你在开始工作前确保所有仓库都是最新的。那么,你还在等什么呢?尝试这个方法,让你的工作流程变得更加高效。最后,你是否还有其他类似的技巧来简化日常任务?--GPT 4

bash git

Inject an instance of a class with all default values

本篇博客详细介绍了如何使用C#编写一个通用的实例生成器,能够为给定类型生成一个实例,并为其属性设置默认值。通过递归地调用Make方法,我们可以处理嵌套的属性,从而生成完整的实例。文章中还提到了如何处理列表、数组和枚举等不同类型的属性,以及如何处理抽象类和接口。 在最后,作者通过一个实际的测试用例展示了生成器的使用方法以及生成的结果。这个生成器在很多场景下都非常实用,比如为单元测试准备数据、为前端提供模拟数据等。在实际应用中,我们还可以根据需要对生成器进行扩展,以支持更多类型的属性和更复杂的对象结构。 那么,您是否有想过如何为您的项目中的类生成实例,而不用手动为每个属性赋值?本文提供的方法是否能帮助您解决这个问题?在实际应用中,您还需要对生成器进行哪些优化和改进?希望本文能为您提供一些启发和灵感。--GPT 4

C# .NET Core

Soft deletion in Entity Framework Core

In this blog post, we explore the implementation of soft deletion in Entity Framework Core, a useful feature for cases where data needs a second step before being permanently deleted from the database. By marking data as "Deleted" rather than removing it completely, we can maintain a record of deleted items for further review or processing. We begin by creating an example entity, `Post`, with properties such as `PostId`, `Title`, `Content`, and `IsDeleted`. The `IsDeleted` property indicates whether an item is considered deleted or not. Deleted items will not be selected by default, but can still be accessed using manual SQL queries. Next, we create a `BloggingContext` class that inherits from `DbContext` and contains a `DbSet<Post>` property. We override the `OnConfiguring` method to configure the SQL Server connection, and the `OnModelCreating` method to add a filter that selects only non-deleted posts. To implement soft deletion, we override the `SaveChanges` method in our `Bl...--GPT 4

C# Entity Framework SQL Server Soft deletion

Support multi-tenant in pure Entity Framework Core

In this blog post, we discuss how to support multi-tenancy in pure Entity Framework Core, a crucial feature that allows data to be separated by different tenants, ensuring no interference between them. The post outlines the process of implementing multi-tenancy without relying on ASP.NET boilerplate, focusing on creating an example entity, configuring the SQL Server connection, and adding filters for tenant-specific data. The example entity, Blog, has a primary key, Id, and a TenantId that represents which tenant the blog belongs to. The table is grouped by TenantId, creating multiple collections of blogs. The BloggingContext class is created, taking a tenantId as input, and the SQL Server connection is configured by overriding the OnConfiguring method. To ensure that developers only access blogs from the current tenant, a filter is added by overriding the OnModelCreating method. Additionally, when inserting an item into the table, the TenantId is automatically set by overriding the ...--GPT 4

ASP.NET Core C# Entity Framework Multi-tenant

Auto update database for ASP.NET Core with Entity Framework

在ASP.NET Core项目中,通过Entity Framework连接到数据库时,我们通常需要执行`dotnet ef database update`脚本来更新数据库。然而,这个过程容易被遗忘,导致问题的发生。那么如何在应用程序启动时自动更新数据库呢? 首先,需要了解自动迁移数据库是有风险的,可能导致数据丢失、处理过时的分支以及迁移失败等问题。因此,除非确保一切安全,否则不建议自动更新数据库。 要实现自动更新数据库,需要在项目中添加以下依赖项: <PackageReference Include="Polly" Version="7.2.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> 借助`Polly`库,可以轻松地重试任务。 接下来,将以下代码复制到项目中: public static IHost MigrateDbContext<TContext>( this IHost host) where TContext : DbContext { // ... } 这段代码为IHost创建了一个扩展方法,允许在应用程序启动后自动升级数据库。它使用应用程序的默认服务提供程序来创建作用域并获取`DBContext`,然后尝试将数据库迁移到最新状态。 如果数据库为空或根本不存在,脚本还可以自动创建数据库。 最后,在启动过程中使用扩展方法,如下所示: public static void Main(string[] args) { CreateHostBuilder(args) .Build() ...--GPT 4

ASP.NET Core C# Entity Framework SQL Server

Limit ASP.NET Core request frequency by IP address

在默认情况下,用户可以无限制地请求ASP.NET Core Web服务器。用户可能会频繁地请求我们的Web服务器并提交大量垃圾数据。此外,过于频繁的请求可能是一种可怕的攻击,可能导致我们的服务中断和大量的金钱损失。 那么我们如何根据IP地址对请求进行分组,限制用户请求的频率,并返回错误信息呢? 已经有一个很好的限制请求速率的库,叫做AspNetCoreRateLimit。 GitHub: [https://github.com/stefanprodan/AspNetCoreRateLimit](https://github.com/stefanprodan/AspNetCoreRateLimit) 但是,这个库太重了,无法通过控制器和操作进行过滤。我必须写一个更简单的库。 首先,编写一个属性: public class LimitPerMin : ActionFilterAttribute {...} 这个属性将在字典中保存所有IP请求频率。如果一个IP匹配我们的限制,就返回`(int)HttpStatusCode.TooManyRequests`。 要使用此属性,只需将其添加到您的控制器或操作中,如下所示: namespace Aiursoft.Account.Controllers { [LimitPerMin] public class AccountController : Controller { } } 当用户尝试在我们的限制范围内请求我们的服务器时,服务器将成功响应以下头信息: 1. x-rate-limit-limit: 1m 2. x-rate-limit-remaining: 30 默认限制是每分钟30个请求。用户在一分钟内无法发送更多请求,否则将被拒绝。 如果您想覆盖默认限制,请像这样使用它: [LimitPerMin(20)] 本文介绍了如何使用ASP.NET Core实现IP地址限制请求频率的方法,通过编写一个简单的属性,可以有效地限制用户请求的频率并返回错误信息。文章还介绍了如何将此属性应用于控制器或操作,以及如何覆盖默认限制。那么,如何根据实际需求进一步优化限制策略呢?在实际应用中,如何确保这...--GPT 4

ASP.NET Core .NET Core IP HTTP

How to run async method in C# synchronous method

在某些情况下,我们可能需要运行一个异步方法并获取其结果,但无法使用`await`关键字,例如在构造函数方法、实现接口同步方法或实现抽象类同步方法中。本文提供了一种解决方案,将异步方法解包并在同步方法中调用。 首先,将以下代码放在任意位置: ```csharp using System.Threading; using System.Threading.Tasks; public static class AsyncHelper { private static readonly TaskFactory _taskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default); public static TResult RunSync<TResult>(Func<Task<TResult>> func) => _taskFactory .StartNew(func) .Unwrap() .GetAwaiter() .GetResult(); public static void RunSync(Func<Task> func) => _taskFactory .StartNew(func) .Unwrap() .GetAwaiter() .GetResult(); } ``` 然后创建一个异步方法,如下所示: ```csharp private static async Task<int> MyAsyncMethod() { // do something async. await Task.Delay(1000); Console.WriteLine("R...--GPT 4

C# .NET Core Async

Consolidate all Entity-Framework database migrations to one migration

本文介绍了如何在不删除任何数据的情况下,整合所有Entity Framework Core代码优先迁移。在代码出错或迁移过多导致编辑器变慢的情况下,可能需要重置所有迁移。但是,直接在代码中删除所有迁移会导致数据库更新失败。因此,本文提供了一个解决方案,分为以下几个步骤: 1. 删除`Migrations`文件夹下的所有`*.cs`文件。 2. 删除数据库中`_EFMIgrationHistory`表中的所有项。 3. 创建一个新的迁移,如:`dotnet ef migrations add Init`。 4. 注释由上一步生成的`20XXXXX_Init.cs`类中的`Up`方法和`Down`方法中的所有内容。 5. 使用当前应用程序的状态更新数据库。此步骤不会更改数据库,而只会在`_EFMigrationHistory`表中创建一个项。这将在数据库中记录一个历史,即`Init`迁移已应用于数据库。 6. 取消注释C#文件中的`Up`和`Down`方法。 7. 如果有版本控制,请检查。 8. 重新运行`dotnet ef database update`。这可能会显示一切都是最新的,这正是我们所期望的。 9. 启动应用程序,应用程序将正常运行。 如果您有其他使用不同数据库的环境,则需要**针对每个数据库**执行以下步骤: 10. 检出步骤7中推送的最新代码。 11. 删除数据库中`_EFMIgrationHistory`表中的所有项。 12. 注释由步骤3生成的`20XXXXX_Init.cs`类中的`Up`方法和`Down`方法中的所有内容。 13. 使用当前应用程序的状态更新数据库。此步骤不会更改数据库,而只会在`_EFMigrationHistory`表中创建一个项。这将在数据库中记录一个历史,即`Init`迁移已应用于数据库。 14. 将代码状态重置为步骤10。例如:`git reset --hard HEAD`。 15. 尝试运行应用程序。 在开始之前,强烈建议您首先备份数据。本文提供的方法仅适用于代码优先的EF Core,并不能确保数据不会丢失。那么,这种方法是否适用于所有场景?是否存在更好的方法来整合迁移?在实践中,您可能需要自己寻找答案。--GPT 4

ASP.NET Core C# .NET Core Entity Framework SQL Server

Upgrade existing class library to .NET Core 3.0

本篇博客讨论了如何将现有的类库升级到最新的.NET Core 3.0。在升级过程中,可能会遇到一些警告和错误。文章详细介绍了如何解决这些问题,以便顺利完成升级。 首先,根据项目类型选择正确的项目文件第一行。对于Web项目,请使用`<Project Sdk="Microsoft.NET.Sdk.Web">`;对于Razor库,请使用`<Project Sdk="Microsoft.NET.Sdk.Razor">`。在这两种情况下,都不需要再次包含`Microsoft.AspNetCore.App`框架。 其次,对于非Razor库和非Web项目,通常不需要`Microsoft.AspNetCore.App`。但是,如果确实需要它,请考虑添加相应的框架引用。 最后,可能会遇到关于C#版本的错误。这个问题可能是因为没有使用最新的Visual Studio。为了解决这个问题,可以在项目文件中添加`<LangVersion>latest</LangVersion>`,然后清理并重新构建项目。 本文提供了一系列解决方案,帮助读者顺利升级现有类库到.NET Core 3.0。在升级过程中,是否还有其他潜在问题需要注意?如何确保项目在升级后仍能正常运行?阅读全文以获取更多详细信息和解决方案。--GPT 4

C# class library .NET Core