您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > .NET

.NET Standard停止更新,它将何去何从?

时间:2020-10-16 11:23:58  来源:  作者:

自从.NET 5 发布以来,许多人都在问它对.NET Standard 意味着什么,想知道它是不是还能吸引主流开发人员的兴趣。

在本文中,我将介绍.NET 5 是如何改善代码共享并替代.NET Standard 的。同时,我还将介绍一些仍然需要.NET Standard 的情况。

TL;DR

.NET 5 将是一个具有一组统一特性和 API 的单一产品,可用于 windows 桌面应用、跨平台移动应用、控制台应用、云服务和网站

为更好地反映这一点,我们更新了目标框架名称(TFM):

  • net5.0。这适用于运行在所有平台上的代码。它合并并替换了netcoreApp和netstandard名称。这个 TFM 总体上只包括跨平台工作的技术(除了一些特例,就像我们在.NET Standard 中所做的那样)。
  • net5.0-windows(以及之后的net6.0-Android和net6.0-IOS)。这些 TFM 代表特定于 OS 的.NET 5 风味,其中包括net5.0加上特定于 OS 的特性。

我们不会再发布.NET Standard 的新版本了,但是.NET 5 和所有将来的版本都会继续支持.NET Standard 2.1 和更早版本。你应该将net5.0(及以后的版本)视为未来共享代码的基础。

由于net5.0是所有这些新 TFM 的共享基础,因此这意味着运行时、库和新的语言特性将围绕这个版本号来运作。例如,为了使用 C# 9,你需要使用net5.0或net5.0-windows。

你的目标应该是什么

.NET 5 和将来所有的版本都会一直支持.NET Standard 2.1 和更早版本。从.NET Standard 目标切换到.NET 5 的唯一理由是可以访问更多的运行时特性、语言特性或 API。因此,你可以将.NET 5 视为.NET Standard 的 vNext。

新代码呢?你还是应该从.NET Standard 2.0 开始还是应该直接进入.NET 5?这要看具体情况。

  • 应用组件。如果你使用库将应用程序分解为多个组件,我的建议是使用netX.Y,其中X.Y是应用程序(或多个应用程序)目标的最低.NET。为简单起见,你可能希望组成应用程序的所有项目都位于同一版本的.NET 上,因为这样以来,你就可以在所有地方都获得相同的 BCL 特性。
  • 可重用的库。如果你要构建计划在 NuGet 上发布的可重用库,则需要考虑覆盖率和可用特性集之间的权衡。.NET Standard 2.0 是.NET Framework 支持的.NET Standard 的最高版本,因此它将为你提供最大的覆盖范围,同时还为你提供了相当大的特性集。我们通常建议你不要以.NET Standard 1.x 为目标,因为麻烦事太多了。如果你不需要支持.NET Framework,则可以使用.NET Standard 2.1 或.NET 5。大多数代码都可以跳过.NET Standard 2.1,直接转到.NET 5。

那到底该怎么办?我的建议是,广泛使用的库最终将同时将.NET Standard 2.0 和.NET 5 作为目标:支持.NET Standard 2.0 可为你提供最大的支持范围,而支持.NET 5 可确保你能为客户提供.NET 5 上最新的平台特性。

在几年内,可重用库的选项仅涉及netX.Y的版本号,这基本上就是为.NET 构建库的标准途径——通常来说,你会希望支持某些较旧的版本,以确保获得最大的采用率。

总结一下:

  • 使用netstandard 2.0在.NET Framework 和其他所有平台之间共享代码。
  • 使用netstandard 2.1在 Mono、Xamarin 和.NET Core 3.x 之间共享代码。
  • 使用net5.0为将来的项目进行代码共享。

.NET 5 如何解决.NET Standard 存在的问题

.NET Standard 让开发人员可轻松创建适用于所有.NET 平台的库。但是,.NET Standard 仍然存在三个问题:

  1. 它的版本更替很慢,这意味着你无法轻松使用最新特性。
  2. 它需要一个解码器环才能将版本映射到.NET 实现。
  3. 它公开了特定于平台的特性,这意味着你无法静态验证代码是否真正可移植。

让我们看看.NET 5 是如何解决这三个问题的。

问题 1:.NET Standard 版本更新缓慢

.NET Standard 是.NET 平台尚未在实现级别融合的时候设计的。这使开发人员很难编写需要在不同环境中运行的代码,因为不同的负载使用了不同的.NET 实现。

.NET Standard 的目标是统一基类库(BCL)的特性集,以便你可以编写可在任何地方运行的库。这对我们很有帮助:.NET Standard 在前 1000 个软件包中得到了 77%以上的支持。而且,如果我们查看 NuGet.org 上最近 6 个月中更新的所有软件包,则采用率是 58%。

支持.NET Standard 的包:

.NET Standard停止更新,它将何去何从?

 

但是单独标准化 API 集会有代价。每当我们添加新的 API 时都需要协调。.NET 开源社区(包括.NET 团队)通过提供新的语言特性、可用性改进、新的跨领域特性(例如Span<T>)或支持新的数据格式或网络协议,以在 BCL 中不断创新前进。

尽管我们可以将新类型作为 NuGet 包来提供,但我们不能以这种方式在现有类型上提供新的 API。因此从一般意义上讲,BCL 中的创新需要交付新版本的.NET Standard。

在.NET Standard 2.0 之前,这并不是什么大问题,因为我们仅对现有的 API 进行了标准化。但是在.NET Standard 2.1 中,我们对全新的 API 进行了标准化,因此我们遇到了很多麻烦。

这种摩擦从何而来?

.NET Standard 是所有.NET 实现都必须支持的 API 集,因此它有一个编辑准则,即所有 API 必须由.NET Standard 审查委员会审查。该委员会由.NET 平台实现者和.NET 社区的代表组成,目标是仅标准化我们可以在所有当前和将来的.NET 平台中真正实现的 API。这些检查是必要的,因为.NET 堆栈的实现方式不同,约束条件也不同。

我们预测到了这种摩擦,这就是为什么我们之前提到.NET Standard 只会标准化至少在一个.NET 实现中提供 API 的原因。一开始这似乎挺合理,但随后,你就意识到.NET Standard 不能频繁发布新版本。因此,如果某个特性错过了某个特定版本,则可能需要等上几年才能发布,甚至可能需要更长时间才能等到这个版本的.NET Standard 得到广泛支持。

对某些特性来说,我们感到机会成本太高了,因此我们采取了非常规的行动来标准化尚未交付的 API(例如IAsyncEnumerable<T>)。但是,对所有特性都这么做,实在是太昂贵了,这就是为什么许多特性仍然错过了.NET Standard 2.1 的原因(例如新的硬件内部函数)。

但是,如果只有一个代码库呢?如果这个代码库需要支持现在让.NET 实现分裂的所有选项,例如同时支持即时(JIT)编译和提前(AOT)编译,又会怎么样?

从一开始,我们就将所有这些选项都纳入了特性设计,而不是事后才考虑。在这种情况下,标准化的 API 集在构造上就是通用的 API 集。一个特性被实现后,由于代码库是共享的,因此这个特性立刻就能被所有人使用。

问题 2:.NET Standard 需要解码环

将 API 集与对应的实现分离,不仅仅是减缓了 API 的可用性,这也意味着我们需要将.NET Standard 版本映射到它们的实现上。随着时间的推移,我需要向越来越多的人解释这种关系,于是发现这种看似简单的想法其实非常复杂。我们尽了最大的努力来简化它,但毕竟这是固有的复杂性,因为 API 集和实现是分开独立提供的。

我们统一了 .NET 平台,在它们下面又增加了一个合成平台,代表了通用的 API 集。这幅受 XKCD 启发的漫画就画得很明白:

.NET Standard停止更新,它将何去何从?

 

.NET 5 要做的就是真正在框架中合并一些部分,从而解决这个问题:.NET 5 提供了一个统一的实现,所有部分都在相同的基础上构建,并因此获得相同的 API 形状和版本号。

问题 3:.NET Standard 公开了特定平台 API

在设计.NET Standard 时,我们必须做出务实的妥协,以免对库生态系统造成过大的破坏。换句话说,我们必须包括一些只适用于Windows 的API(例如文件系统ACL、注册表、WMI 等)。展望未来,我们将避免在 net5.0、net6.0和以后的版本中添加特定于平台的 API。但我们无法预测未来,例如,借助 Blazor WebAssembly,我们最近添加了一个新环境,可以在其中运行.NET,可浏览器的沙箱中不支持某些跨平台 API(例如线程或进程控制)。

很多人抱怨说,这类 API 就像“地雷”一样——代码编译没有错误,因此似乎可以移植到任何平台,但是在没有针对给定 API 实现的平台上运行时就会出现运行时错误。

从.NET 5 开始,我们将默认随附带有 SDK 的分析器和代码修复程序,其中包括平台兼容性分析器,该分析器可检测到你准备运行的平台上不支持哪些API,并报告相应的意外使用情况。此特性替代了 Microsoft.DotNet.Analyzers.Compatibility NuGet 包。

首先,让我们看一下 Windows 专属的 API。

处理特定于 Windows 的 API

创建以 net5.0 为目标的项目时,可以引用 Microsoft.Win32.Registry 包。但当你开始使用它时,会收到以下警告:

private static string GetLoggingDirectory()
{    
     using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SoftwareFabrikam"))
     { 
          if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
              return configuredPath;
     }   
  string exePath = Process.GetCurrentProcess().MainModule.FileName; 
  string folder = Path.GetDirectoryName(exePath); 
  return Path.Combine(folder, "Logging");
}
CA1416: 'RegistryKey.OpenSubKey(string)' is supported on 'windows'
CA1416: 'Registry.CurrentUser' is supported on 'windows'
CA1416: 'RegistryKey.GetValue(string?)' is supported on 'windows'

关于如何解决这些警告,你有三个选项:

  1. 守护调用。你可以使用OperatingSystem.IsWindows(),在调用 API 之前检查你是否在 Windows 上运行。
  2. 将调用标记为 Windows 专属。在某些情况下,可以通过[SupportedOSPlatform("windows")]将调用成员标记为平台专属。
  3. 删除代码。通常这不是你想要的,因为这意味着 Windows 用户使用你的代码时会损失一些内容,但是对于存在跨平台替代方案的情况,你最好放弃那些平台专属的代码。例如,可以使用 XML 配置文件来替代注册表。
  4. 禁止警告。你当然可以通过.editorconfig或#pragmawarningdisable来作弊,简单地禁用警告。但是,在使用特定于平台的 API 时,你应该选择选项(1)和(2)。

为了守护调用,请在 System.OperatingSystem 类上使用新的静态方法,例如:

private static string GetLoggingDirectory()
{   
    if (OperatingSystem.IsWindows())  
    {  
        using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SoftwareFabrikam"))  
        {
             if (key?.GetValue("LoggingDirectoryPath") is string configuredPath) 
               return configuredPath; 
        }
    }   
  string exePath = Process.GetCurrentProcess().MainModule.FileName;   
  string folder = Path.GetDirectoryName(exePath);   
  return Path.Combine(folder, "Logging");
}

将代码标记为 Windows 专属,请应用新的SupportedOSPlatform属性:

[SupportedOSPlatform("windows")]
private static string GetLoggingDirectory()
{ 
    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SoftwareFabrikam"))
    {  
        if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
          return configuredPath;
    } 
  string exePath = Process.GetCurrentProcess().MainModule.FileName; 
  string folder = Path.GetDirectoryName(exePath);   
  return Path.Combine(folder, "Logging");
}

在这两种情况下,使用注册表的警告都会消失。

关键区别在于,在第二个示例中,分析器现在将针对GetLoggingDirectory()的调用站点发出警告,因为它现在被视为 Windows 特定的 API。换句话说,你将进行平台检查的要求转发给了调用者。

[SupportedOSPlatform]属性可以应用于成员、类型或程序集级别。BCL 本身也使用此属性。例如,程序集Microsoft.Win32.Registry应用了此属性,所以分析器能先知道注册表是 Windows 特定的 API。

请注意,如果你以net5.0-windows为目标,此属性将自动应用于你的程序集。这意味着从net5.0-windows使用 Windows 专属的 API 永远不会产生任何警告,因为你的整个程序集都被视为 Windows 专属的。

处理 Blazor WebAssembly 中不支持的 API

Blazor WebAssembly 项目在浏览器沙箱中运行,这限制了你可以使用的 API。例如,尽管线程和进程创建都是跨平台的 API,但我们无法使这些 API 在 Blazor WebAssembly 中运行,这意味着它们会抛出PlatformNotSupportedException警告。我们已经用[UnsupportedOSPlatform("browser")]标记了这些 API。

假设,你将GetLoggingDirectory()方法复制并粘贴到一个 Blazor WebAssembly 应用程序中。

private static string GetLoggingDirectory()
{
    //... 
    string exePath = Process.GetCurrentProcess().MainModule.FileName; 
    string folder = Path.GetDirectoryName(exePath);   
    return Path.Combine(folder, "Logging");
}

你会收到以下警告:

CA1416 'Process.GetCurrentProcess()' is unsupported on 'browser'
CA1416 'Process.MainModule' is unsupported on 'browser'

为了处理这些警告,你的选项和处理 Windows 特定的 API 时基本相同。
你可以守护调用

private static string GetLoggingDirectory()
{   
   //... 
   if (!OperatingSystem.IsBrowser()) 
   {       
     string exePath = Process.GetCurrentProcess().MainModule.FileName;      
     string folder = Path.GetDirectoryName(exePath);  
     return Path.Combine(folder, "Logging");  
   }   
  else  
  {       
    return string.Empty;  
  }
}

或者,你可以将成员标记为 Blazor WebAssembly 不支持的成员:

[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{  
  //...  
  string exePath = Process.GetCurrentProcess().MainModule.FileName;   
  string folder = Path.GetDirectoryName(exePath);  
  return Path.Combine(folder, "Logging");
}

由于浏览器沙箱的限制非常严格,因此不能预期所有类库和 NuGet 包都能在 Blazor WebAssembly 中工作。此外,绝大多数库也不一定能在 Blazor WebAssembly 中运行。

因此,目标为net5.0的常规类库不会看到 Blazor WebAssembly 不支持的 API 警告。你必须通过在项目文件中添加项,来显式声明你打算在 Blazor WebAssembly 中支持你的项目:

<Project Sdk="Microsoft.NET.Sdk">   
  
  <PropertyGroup>   
     <TargetFramework>net5.0</TargetFramework> 
 </PropertyGroup>  

<ItemGroup>   
       <SupportedPlatform Include="browser" />  
 </ItemGroup>  

</Project>

如果你要构建一个 Blazor WebAssembly 应用程序,则不必这样做,因为Microsoft.NET.Sdk.BlazorWebAssembly SDK 会自动执行此操作。

.NET 5 作为.NET Standard 和.NET Core 的组合

.NET 5 及其后续版本将是一个单一代码库,它支持桌面应用、移动应用、云服务、网站以及未来.NET 将会运行的任何环境。

你可能会认为“等等,这听起来不错,但是如果有人想创建一个全新的实现该怎么办”。这也是可以的。但实际上没有人会从头开始。这样的实现很可能是当前代码库( dotnet/runtime )的分支。例如,Tizen(三星用于智能设备的平台)使用了一个经过少量改动的.NET Core,并且在顶层使用了一个三星定制的应用模型。

分叉保留了合并关系,维护人员可以从不受其更改影响的 BCL 创新中受益,从而继续从 dotnet/runtime 仓库中拉取新更改。这与 linux 发行版的机制非常相似。

当然,在某些情况下,你可能想创建一种非常不同的.NET“类别”,例如在没有当前 BCL 的情况下最小化运行时。但这意味着它无论如何都无法利用现有的.NET 库生态系统,也就是说,它也不会实现.NET Standard。我们对这个方向总体来说并不感兴趣,但是.NET Standard 和.NET Core 的融合并不能阻止这一点,也不会为其增加障碍。

.NET 版本控制

作为库作者,你可能想知道.NET 5 何时才能得到广泛支持。展望未来,我们将在每年 11 月发布.NET,每隔一年将发布一个长期支持(LTS)版本。

.NET 5 将于 2020 年 11 月发布,.NET 6 将于 2021 年 11 月发布,是 LTS 版。我们定下了这个固定的时间表,以便大家更轻松地安排更新计划(如果你是应用开发人员),和预测对.NET 版本的支持需求(如果你是库开发人员)。

由于.NET Core 能够并行安装,因此新版本的采用速度相当快,其中 LTS 版本最为流行。实际上,.NET Core3.1 是有史以来普及最快的.NET 版本。

.NET Standard停止更新,它将何去何从?

.NET 5 时间表

可以预计每次交付时,我们都会一并更新所有框架名称。例如,计划可能是这个样子:

.NET Standard停止更新,它将何去何从?

 

换句话说,你基本上可以指望:无论我们在 BCL 中所做的创新如何,无论它们运行在哪个平台上,你都将能在所有应用模型中使用它。这也意味着,只要运行最新版本的.NET,就始终可以在所有应用模型中使用为最新的net框架提供的库。

这种模式消除了.NET Standard 版本控制的复杂性,因为每次发布新版时,你都可以假定所有平台都将立即且完全支持新版本。我们还使用前缀命名约定来巩固这一承诺。

.NET 的新版本可能会增加对其他平台的支持。例如,我们将为.NET 6 添加对 Android 和 iOS 的支持。相反,我们可能会停止支持不再流行的平台。.NET 6 中就没有net5.0-someoldos目标框架。我们没有移除某个平台的计划,但是这种模式下存在这种可能性。这会是一件大事,提前无法预料,而且会提前很长时间宣布。这与.NET Standard 使用的模式相同,例如,Windows Phone 已经无法运行更高版本的.NET Standard 了。

为什么没有 WebAssembly 的 TFM

我们最初考虑为 WebAssembly 添加 TFM,例如net5.0-wasm。我们出于以下原因决定不这样做:

  • WebAssembly 更像是指令集(例如 x86 或 x64),而非操作系统。而且,我们通常不会在不同的架构之间提供不同的 API。
  • 浏览器沙箱中的 WebAssembly 执行模型是一个重大创新,但我们认为仅将其建模为一个运行时检查更有意义。与检查 Windows 和 Linux 的方式类似,你可以使用 OperatingSystem 类型。由于这与指令集无关,因此该方法称为IsBrowser()而不是IsWebAssembly()。
  • WebAssembly 有运行时标识符( RID ),称为browser和browser-wasm。它们允许包作者以浏览器中的 WebAssembly 为目标时部署不同的二进制文件。这对于需要事先编译为 Web 程序集的原生代码特别有用。

如上所述,我们标记了浏览器沙箱中不支持的 API,例如System.Diagnostics.Process。如果你是从浏览器应用中使用这些 API,则会收到警告,告知你不支持该 API。

总结

net5.0适用于在各种平台上运行的代码。它合并并替换了netcoreapp和netstandard名称。我们还有特定于平台的框架,例如net5.0-windows(以及后来的net6.0-android和net6.0-ios)。

由于标准与其实现之间没有区别,因此你可以比.NET Standard 更快地利用新特性。而且,由于采用了命名约定,你就能轻松判断谁可以使用给定的库,而无需查阅.NET Standard 版本表。

.NET Standard 2.1 将是.NET Standard 的最后版本,而.NET 5 和所有将来的版本将继续支持.NET Standard 2.1 和更早版本。你应该将 net5.0(及以后的版本)视为共享代码的基础。

原文链接:

https://devblogs.microsoft.com/dotnet/the-future-of-net-standard/



Tags:.NET   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
编译和反编译.NET 中的编译是把开发人员写的 C# 代码转化为计算机可理解的代码的过程,也就是中间语言代码(IL代码)。在这个过程中,C# 源代码被转换为可执行文件(exe或者dll 文件)...【详细内容】
2022-07-15  Tags: .NET  点击:(1)  评论:(0)  加入收藏
我们在开发 webapi 项目时如果遇到 api 接口需要同时支持多个版本的时候,比如接口修改了入参之后但是又希望支持老版本的前端(这里的前端可能是网页,可能是app,小程序 等等)进行...【详细内容】
2022-07-14  Tags: .NET  点击:(3)  评论:(0)  加入收藏
什么是.NET.NET 是由 Microsoft 创建的开源开发平台,用于生成多种不同类型的应用程序,主要支持C#、F#及VB。.NET程序运行原理.NET程序的运行是由其虚拟机CLR(公共语言运行时)把...【详细内容】
2022-06-21  Tags: .NET  点击:(26)  评论:(0)  加入收藏
项目介绍一套基于.NetCore+Vue2/Vue3+Element plus+uniapp,采用前后端分离方式,全自动生成PC与移动端代码的快速开发脚手架;支持移动端(uniapp)ios/android/h5/微信小程序。 Vu...【详细内容】
2022-06-13  Tags: .NET  点击:(56)  评论:(0)  加入收藏
多年前借鉴b/s优势实现基于.net的c/s框架 本框架未采用.NET固有的WCF通讯解决方案,而使用传统http数据加密方式.框架初始和传统客户端升级方式一样检查新版本,如有则下载升级...【详细内容】
2022-06-05  Tags: .NET  点击:(30)  评论:(0)  加入收藏
Asp.Net Core Identity 是.Net自带的身份认证系统,支持用户界面 (UI) 登录功能,并且管理用户、密码、配置文件数据、角色、声明、令牌、电子邮件确认等等。使用Visual Studio...【详细内容】
2022-06-05  Tags: .NET  点击:(35)  评论:(0)  加入收藏
安装Hangfire新建ASP.NET Core空 项目,.Net Core版本3.1 往*.csproj添加包引用,添加新的PackageReference标记。如下所示。请注意,下面代码段中的版本可能已经过时,如有需要,请使...【详细内容】
2022-05-07  Tags: .NET  点击:(76)  评论:(0)  加入收藏
 B/S架构的Web程序几乎占据了应用软件的绝大多数市场,但是C/S架构的WinForm、WPF客户端程序依然具有很实用的价值,如设计类软件 AutoCAD与Autodesk Revit、WPS、IT类的集成开...【详细内容】
2022-04-27  Tags: .NET  点击:(153)  评论:(0)  加入收藏
前几天有个老项目找到我,有多老呢?比我工作年限都长,见到这个项目我还得叫一声前辈。这个项目目前使用非常稳定,十多年了没怎么更新过,现在客户想加一个小功能:在线预览Word文档。...【详细内容】
2022-04-27  Tags: .NET  点击:(65)  评论:(0)  加入收藏
之前,我们已经了解了ASP.NET Core中的身份认证,现在,我们来聊一下授权。老规矩,示例程序源码XXTk.Auth.Samples已经提交了,需要的请自取。概述ASP.NET Core中的授权方式有很多,我...【详细内容】
2022-04-20  Tags: .NET  点击:(143)  评论:(0)  加入收藏
▌简易百科推荐
编译和反编译.NET 中的编译是把开发人员写的 C# 代码转化为计算机可理解的代码的过程,也就是中间语言代码(IL代码)。在这个过程中,C# 源代码被转换为可执行文件(exe或者dll 文件)...【详细内容】
2022-07-15  IT狂人日记    Tags:.NET   点击:(1)  评论:(0)  加入收藏
我们在开发 webapi 项目时如果遇到 api 接口需要同时支持多个版本的时候,比如接口修改了入参之后但是又希望支持老版本的前端(这里的前端可能是网页,可能是app,小程序 等等)进行...【详细内容】
2022-07-14  IT技术资源爱好者    Tags:.Net   点击:(3)  评论:(0)  加入收藏
什么是.NET.NET 是由 Microsoft 创建的开源开发平台,用于生成多种不同类型的应用程序,主要支持C#、F#及VB。.NET程序运行原理.NET程序的运行是由其虚拟机CLR(公共语言运行时)把...【详细内容】
2022-06-21  威步上海    Tags:.NET   点击:(26)  评论:(0)  加入收藏
Asp.Net Core Identity 是.Net自带的身份认证系统,支持用户界面 (UI) 登录功能,并且管理用户、密码、配置文件数据、角色、声明、令牌、电子邮件确认等等。使用Visual Studio...【详细内容】
2022-06-05  海椰人  博客园  Tags:.Net   点击:(35)  评论:(0)  加入收藏
安装Hangfire新建ASP.NET Core空 项目,.Net Core版本3.1 往*.csproj添加包引用,添加新的PackageReference标记。如下所示。请注意,下面代码段中的版本可能已经过时,如有需要,请使...【详细内容】
2022-05-07  壮志林云    Tags:.NET   点击:(76)  评论:(0)  加入收藏
 B/S架构的Web程序几乎占据了应用软件的绝大多数市场,但是C/S架构的WinForm、WPF客户端程序依然具有很实用的价值,如设计类软件 AutoCAD与Autodesk Revit、WPS、IT类的集成开...【详细内容】
2022-04-27  IT技术资源爱好者  博客园  Tags:.NET   点击:(153)  评论:(0)  加入收藏
前几天有个老项目找到我,有多老呢?比我工作年限都长,见到这个项目我还得叫一声前辈。这个项目目前使用非常稳定,十多年了没怎么更新过,现在客户想加一个小功能:在线预览Word文档。...【详细内容】
2022-04-27  海椰人  博客园  Tags:.Net   点击:(65)  评论:(0)  加入收藏
之前,我们已经了解了ASP.NET Core中的身份认证,现在,我们来聊一下授权。老规矩,示例程序源码XXTk.Auth.Samples已经提交了,需要的请自取。概述ASP.NET Core中的授权方式有很多,我...【详细内容】
2022-04-20  日行四善  博客园  Tags:授权   点击:(143)  评论:(0)  加入收藏
序言本文将分别介绍 Authentication(认证) 和 Authorization(授权)。并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能。 相关名词Authentication 和 Author...【详细内容】
2022-04-18  芦荟柚子茶  博客园  Tags:ASP.NET   点击:(197)  评论:(0)  加入收藏
前言由于客户网络安全限制,连接到互联网的设备不能访问内网。需要先从客户端应用中导出数据到文件,再将文件复制到U盘,最后通过内网机器上传数据。如何保证,在复制、传输过程中,...【详细内容】
2022-03-22  My IO    Tags:.NET Core   点击:(125)  评论:(0)  加入收藏
站内最新
站内热门
站内头条