将传统 ASP.NET 应用迁移到 .NET Core

点击蓝字

关注我

现在越来越多的人在谈论. NET Core。诚然,.NET Core 是未来, 但是.NET Framework 仍在支持, 因为大量的应用程序无法在短时间内迁移。

.NET Core 和 .NET Framework 就像电动汽车和汽油动力汽车。汽油车是成熟的,你可以毫无任何问题驾驶它,但电动车有它们的优势,并正在取代汽油车。所以,不要误会,你应该从今天开始迁移到. NET Core。

长文预警

640?wx_fmt=gif

我已经迁移了几个运行在完整.NET Framework和IIS上的传统ASP.NET/MVC项目到ASP.NET Core 2.x,可以运行在IIS或非IIS环境下。

我的博客是其中之一。这是一个有10年历史的博客系统,最初由 ASP.NET 2.0 Web Form以及Visual Basic编写。从2008年起,我一直在面向最新的.NET技术更新代码库。.NET Core版本的博客系统将在今年年底到来。我写这篇文章,记录我遇到的路障和如何解决它们的方法。

这篇文章针对的是新接触.NET Core,但有.NET Framework经验的开发人员,帮助他们将现有的应用更平滑的过渡到.NET Core上。 smiley_13.png

640?wx_fmt=gif1

迁移或重写

有时候,我更喜欢用“重写“而不是”迁移“这个词,因为在有些情况下,.NET Core和.NET Framework是完全不同的两个东西。

根据我的经验,大部分前端代码可以只做少量修改就直接移植到.NET Core,因为它们的本质毕竟是服务器技术无关的,天生跨平台的技术。至于后端代码,迁移成本取决于它们对Windows及IIS的耦合程度。我理解,有些应用会充分利用Windows 及 IIS 的特性,这样开发者就可以避免自己费力去实现一些功能。这些包括计划任务、注册表、活动目录或Windows服务等。这些并不能够直接迁移,因为.NET Core是跨平台的。对于这些部分,你可能需要考虑从重新设计业务逻辑,想一种可以实现相同功能,但不依赖于Windows 或IIS 组件的方法。

对于无法迁移的历史遗留代码,你可能需要考虑重新设计整个应用的架构,将这些功能作为REST API暴露出来,可以使用.NET Framework上的ASP.NET Web API来实现。这样的话,你的ASP.NET Core 应用得以继续使用这些API并继续完成业务功能。

即使你的应用使用了WCF服务,甚至更老的 ASMX 服务,也是可以搞的。因为.NET Core目前有WCF客户端可以调用WCF。

2

NuGet 包管理

请确保你需要使用的NuGet包支持 .NET Core 或 .NET Standard。如果不支持,那么你需要研究有没有可以替换的NuGet包,或者你是否能够自己写代码去实现相同的功能。

.NET Standard 意味着这个包可以同时使用在.NET Framework 4.6.1+ 以及.NET Core,这是取代老的 Portable Class Library (PCL)的技术。所以,如果你看到一个包的依赖项里有.NET Standard,这意味着你能够将它安装到你的.NET Core工程中。

部分包,比如NLog有专门的.NET Core版本,比如 NLog.Web.AspNetCore,你应该选择使用这样的版本。

640?wx_fmt=png


你依然可以在.NET Core工程里引用一个.NET Framework的包,但是这会让你的应用只能跑在Windows上smiley_0.png,不推荐这么做。

我列出了一些热门使用的NuGet 包,它们都已经支持.NET Core:

NLog.Web.AspNetCore

Newtonsoft.Json

HtmlAgilityPack

RestSharp

NUnit

Dapper

AutoMapper

Moq

对于客户端包,比如 jQuery,请不要使用NuGet 将它们安装到.NET Core工程中,参见本文的 “客户端包管理” 章节。

如果你使用 Visual Studio Code 做 .NET Core 开发,请注意,安装NuGet包的命令不是 Install-Package,那是给Visual Studio的 PowerShell host用的,在VSCode里,你需要使用dotnet CLI工具,比如:

dotnet add package Newtonsoft.Json

参见 https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-add-package

640?wx_fmt=png

3

客户端包管理

ASP.NET Core 曾经使用 Bower 去管理客户端包。但在最新的ASP.NET Core 2.1 里,Bower 已经被移除了,因为作者不干了smiley_11.png。因此,微软默认使用自家的包管理器 “Library Manager” 也叫 “libman” 去管理前端包。它能够在 Visual StudioVisual Studio Code 中使用,甚至也能用 CLI 在命令行下使用。

640?wx_fmt=png

libman.json 可以直接编辑,也能在UI中更改,都有智能感知支持。我的建议是,如果你的应用不是重客户端的话,使用 libman 去管理前端包,因为其他技术比如NPM 太重量级了。你会希望在你的编译服务器上安装和配置NodeJS以及其他一切东西,仅仅为了拉取一个jQuery 库。


更多详情可参见官方文档 https://docs.microsoft.com/en-us/aspnet/core/client-side/libman/?view=aspnetcore-2.1

640?wx_fmt=png

4

Html / JavaScript / CSS

你可以直接将这些文件复制到.NET Core工程里。但是请确保你已经把文件路径修改正确,比如CSS里的图片文件路径。因为传统ASP.NET / MVC 模板默认使用 “/Content/” 目录,而.NET Core模板使用“/css/”, “/js/”, “/lib/” 等目录,这并不是强制的,只是约定俗成的规范。

640?wx_fmt=png

如果你希望捆绑并压缩CSS 和JS 文件,有许多工具可以办到。我个人喜欢用VS的一款插件,叫做 “Bundler & Minifier” ,你可以从这里获取https://github.com/madskristensen/BundlerMinifier.

这款插件可以在开发时生成捆绑及压缩的文件,但非编译或运行时。

640?wx_fmt=gif

5

App_Data 文件夹

在传统ASP.NET/MVC 应用中,你可以将数据文件保存到一个名为“App_Data”的特殊文件夹中,但这个东西在.NET Core里不复存在了。为了实现类似的功能,你需要自己创建一个名为“App_Data” 的文件夹,但位于“wwwroot”目录之外。

640?wx_fmt=png

然后像这样使用

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

    // set

    string baseDir = env.ContentRootPath;

    AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(baseDir, "App_Data"));

 

    // use

    var feedDirectoryPath = $"{AppDomain.CurrentDomain.GetData("DataDirectory")}\\feed";

}

640?wx_fmt=gif

6

自定义 Http Headers

在传统ASP.NET里,你可以在Web.Config 里像这样为每个响应都配置自定义的HTTP Header:

<httpProtocol>

  <customHeaders>

    <add name="X-Content-Type-Options" value="nosniff" />

  </customHeaders>

</httpProtocol>

而在.NET Core里,如果你希望脱离Windows去部署你的应用,不可以使用Web.config文件。因此,你需要一个三方的 NuGet 包来完成这个功能:NetEscapades.AspNetCore.SecurityHeaders

app.UseSecurityHeaders(new HeaderPolicyCollection()

    .AddCustomHeader("X-UA-Compatible", "IE=edge")

    .AddCustomHeader("X-Developed-By", "Edi Wang")

);

详情参考 https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders

640?wx_fmt=png

7

获取客户端IP地址以及 HttpContext

在传统ASP.NET 里,我们能够通过 Request.UserHostAddress 来获取客户端IP地址。但这个属性在 ASP.NET Core 2.x 里是不存在的。我们需要通过另一种方式获取HTTP 请求信息。

1. 在你的 MVC 控制器里定义一个私有变量

private IHttpContextAccessor _accessor;

2.  使用构造函数注入初始化它

public SomeController(IHttpContextAccessor accessor)

{

    _accessor = accessor;

}

3. 获取客户端IP地址

_accessor.HttpContext.Connection.RemoteIpAddress.ToString()

就是如此简单。

如果你的 ASP.NET Core 工程是用MVC默认模板创建的,针对HttpContextAcccessor 依赖注入注册应该在Startup.cs 中完成:

services.AddHttpContextAccessor();

services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

RemoteIpAddress 的类型是 IPAddress 并不是string。它包含 IPv4, IPv6 以及其他信息。这和传统ASP.NET不太一样,对我们更加有用一些。

640?wx_fmt=png

如果你希望在Razor 视图(cshtml) 里使用,只需要用 @inject 指令注入到view中:

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor

使用方法:

Client IP: @HttpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString()

640?wx_fmt=gif

8

JsonResult

默认情况下,ASP.NET Core 会使用 camelCase 序列化 JsonResult ,而传统 ASP.NET MVC 使用的是PascalCase,这会导致依赖Json结果的 JavaScript 代码爆掉。

例如以下代码:

public IActionResult JsonTest()

{

    return Json(new { Foo = 1, Goo = true, Koo = "Test" });

}

它会返回camelCase 的Json给客户端:

640?wx_fmt=png

如果你有大量JavaScript 代码并不能及时改为使用camelCase,你仍然可以配置 ASP.NET Core 向客户端输出 PascalCase 的Json

public void ConfigureServices(IServiceCollection services)

{

    // Add framework services.

    services.AddMvc()

        .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

}

现在,之前的代码会返回PascalCase 的结果:

640?wx_fmt=png640?wx_fmt=gif1

HttpModules 和 HttpHandlers

这两者在ASP.NET Core中被替换为了 Middleware。但在迁移之前,你可以考虑使用别的方法,在一个普通ASP.NET Core Controller 中实现这些功能。

例如,我的老博客系统里有个名为“opml.axd” 的HttpHandler 作用是向客户端输出一个XML文档,这其实完全可以用 Controller 来实现:

public async Task<IActionResult> Index()

{

    var opmlDataFile = $"{AppDomain.CurrentDomain.GetData(Constants.DataDirectory)}\\opml.xml";

    if (!System.IO.File.Exists(opmlDataFile))

    {

        Logger.LogInformation($"OPML file not found, writing new file on {opmlDataFile}");

 

        await WriteOpmlFileAsync(HttpContext);

        if (!System.IO.File.Exists(opmlDataFile))

        {

            Logger.LogInformation($"OPML file still not found, something just went very very wrong...");

            return NotFound();

        }

    }

 

    string opmlContent = await Utils.ReadTextAsync(opmlDataFile, Encoding.UTF8);

    if (opmlContent.Length > 0)

    {

        return Content(opmlContent, "text/xml");

    }

 

    return NotFound();

}

我也曾经使用HttpHandler 完成Open Search,RSS/Atom等功能,它们也能够被 重写为Controller。

对于其他一些不能够被重写为MVC Controller的组件,例如处理特殊拓展名的请求。请参见:

https://docs.microsoft.com/en-us/aspnet/core/migration/http-modules?view=aspnetcore-2.1

640?wx_fmt=png

10

IIS URL Rewrite

你依然可以使用和旧应用里完全一样的配置文件,不管你的 .NET Core 应用是否部署在IIS上。

例如,在应用根目录底下创建一个名为"UrlRewrite.xml"的文件,内容如下:

<rewrite>

  <rules>

    <rule name="Redirect Misc Homepage URLs to canonical homepage URL" stopProcessing="false">

      <match url="(index|default).(aspx?|htm|s?html|php|pl|jsp|cfm)"/>

      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">

        <add input="{REQUEST_METHOD}" pattern="GET"/>

      </conditions>

      <action type="Redirect" url="/"/>

    </rule>

  </rules>

</rewrite>

注意:你必须把这个文件设置为always copy到输出目录,不然无效!smiley_11.png

<ItemGroup>

  <None Update="UrlRewrite.xml">

    <CopyToOutputDirectory>Always</CopyToOutputDirectory>

  </None>

</ItemGroup>

打开 Startup.cs,在Configure 方法中添加如下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

    ...

    using (var urlRewriteStreamReader = File.OpenText("UrlRewrite.xml"))

    {

        var options = new RewriteOptions().AddIISUrlRewrite(urlRewriteStreamReader);

        app.UseRewriter(options);

    }

    ...

}

这在我之前的文章中提到过https://edi.wang/post/2018/9/18/prevent-image-hotlink-aspnet-core.

更多选项和用法可以参考 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/url-rewriting?view=aspnetcore-2.1

640?wx_fmt=png

11

Web.config

Web.config 文件并没有完全消亡。在 In .NET Core 里,一个 web.config 文件仍然用于在IIS环境下部署网站。在这种场景下,Web.config 里的配置仅作用于 IIS,和你的应用代码没有任何关系。可以参考 https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/index?view=aspnetcore-2.1#configuration-of-iis-with-webconfig

一个典型的IIS下部署ASP.NET Core应用的web.config 文件如下:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <location path="." inheritInChildApplications="false">

    <system.webServer>

      <handlers>

        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />

      </handlers>

      <aspNetCore processPath="dotnet" arguments=".\Moonglade.Web.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" />

    </system.webServer>

  </location>

</configuration>

曾经的 AppSettings 节点可迁移到 appsettings.json,在这篇文章中有详解:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1


640?wx_fmt=gif

12

Session 和 Cookie

ASP.NET Core 默认没有开启Session支持,你必须手工添加Session 支持。

services.AddDistributedMemoryCache();

services.AddSession(options =>

{

    options.IdleTimeout = TimeSpan.FromMinutes(20);

    options.Cookie.HttpOnly = true;

});

以及

app.UseSession();

设定和获取Session值:

HttpContext.Session.SetString("CaptchaCode", result.CaptchaCode);

HttpContext.Session.GetString("CaptchaCode");

清除值:

context.Session.Remove("CaptchaCode");

详情参见:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-2.1

640?wx_fmt=png

13

Html.Action

我们曾经使用 Html.Action 去调用一个Action ,返回一个Partial View ,然后放在主要的View 中显示,比如layout页。这在Layout页面中的应用非常广泛,比如在一个博客系统中显示分类列表之类的小部件。

@Html.Action("GetTreeList", "Category")

在ASP.NET Core里,它被替换为了 ViewComponents,参见 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components

一个要注意的地方是Invoke方法只能是 async 签名的smiley_11.png

async Task<IViewComponentResult> InvokeAsync()

但如果你的代码并不是天生异步的,为了不让编译器警报,你可以加入这行代码:

await Task.CompletedTask;

640?wx_fmt=png

14

检查运行环境是 Debug 或 Release

在我的老系统里,我使用 HttpContext.Current.IsDebuggingEnabled 去检查当前运行环境是否为Debug,并在标题栏上显示 “(Debug)” 字样。

@if (HttpContext.Current.IsDebuggingEnabled)

{

    <text>(Debug)</text>

}

在 ASP.NET Core 里,我们可以使用新的razor tag helper 去完成这件事

<environment include="Development">

    (Debug)

</environment>

在下面的章节里,你会看到更多razor tag helper 的用法。

640?wx_fmt=png

15

新的Razor Tag Helpers

Tag helper 可以帮助你讲老的HTML helper 简化为更加面向HTML可读的代码,例如一个表单,我们曾经要这样写:

640?wx_fmt=png

转换为 Tag Helpers 的结果是这样的:

640?wx_fmt=png

我个人最喜欢的功能是给JS或CSS文件自动增加版本字符串:

<script src="~/js/app/ediblog.app.min.js" asp-append-version="true"></script>

它的结果是:

<script src="/js/app/ediblog.app.min.js?v=lvNJVuWBoD_RVZwyBT15T_i3_ZuEIaV_w0t7zI_UYxY"></script>

新的razor 语法能够兼容以前的 HTML helpers,也就是说,你依然能在ASP.NET Core中毫无问题的使用老的 HTML helpers。如果你的应用迁移时间紧迫,你可以尽管先使用老代码,随后再逐步转换到Tag Helpers。


完整的介绍和语法列表,可参见https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-2.1


640?wx_fmt=png

16

Anti-Forgery Token

Anti-forgery token 有一些改进。首先,你能够自定义cookie 以及字段的名字了。

services.AddAntiforgery(options =>

{

    options.Cookie.Name = "X-CSRF-TOKEN-MOONGLADE";

    options.FormFieldName = "CSRF-TOKEN-MOONGLADE-FORM";

});

第二,你再也不需要手工给每一个表单都增加这行代码了:

@Html.AntiForgeryToken()

如果你使用新的form tag helper,那么anti-forgery 字段会自动在输出到客户端时自动加上。

640?wx_fmt=png

但你依然需要在后台对应的Action上加上 [ValidateAntiForgeryToken] 属性。

然而,有另一种自动给每一个POST请求都验证anti-forgery token 的办法。

services.AddMvc(options =>

options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));

或者你可以单独给一个 Controller 加上这个属性。

[Authorize]

[AutoValidateAntiforgeryToken]

public class ManageController : Controller

640?wx_fmt=png

17

对非Controller 使用依赖注入

ASP.NET Core 有自带的 DI 框架可以用在 Controller 上。我们可以修改一个Controller 的构造函数去注入它运行所依赖的服务。

public class HomeController : Controller

{

    private readonly IDateTime _dateTime;

 

    public HomeController(IDateTime dateTime)

    {

        _dateTime = dateTime;

    }

}

但这不意味着自带的DI框架只能用在Controller 上。对于其他类,你可以使用完全一样的DI,例如,我自定义的类,也可以使用构造函数注入:

public class CommentService : MoongladeService

{

    private readonly EmailService _emailService;

 

    public CommentService(MoongladeDbContext context,

        ILogger<CommentService> logger,

        IOptions<AppSettings> settings,

        EmailService emailService) : base(context, logger, settings)

    {

        _emailService = emailService;

    }

   

       // ....

}

方法是,只要你把自定义的类注册到Startup.cs中的 DI 容器里即可。

services.AddTransient<CommentService>();

更多ASP.NET Core 依赖注入的使用方法参见 https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/dependency-injection?view=aspnetcore-2.1

640?wx_fmt=png

18

API 行为不一致

有些来自传统 ASP.NET 的代码可以无错误编译通过,但这不保证运行时能够成功。比如,这段来自ASP.NET (.NET Framework) 的代码在 ASP.NET Core 中会抛出异常:

var buffer = new byte[context.Request.Body.Length];

context.Request.Body.Read(buffer, 0, buffer.Length);

var xml = Encoding.Default.GetString(buffer);

它的结果是:

System.NotSupportedException: Specified method is not supported.

at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.get_Length()

在.NET Core里,我们需要用一种不同的方式去实现:

var xml = await new StreamReader(context.Request.Body, Encoding.Default).ReadToEndAsync();

640?wx_fmt=gif

19

小心GDPR 带来的问题

ASP.NET Core 2.1 默认添加了 GDPR 的支持,但也会给我们带来一些问题。关于GDPR可参见 https://docs.microsoft.com/en-us/aspnet/core/security/gdpr?view=aspnetcore-2.1

主要问题是,在用户接受GDPR协议之前,Cookie 是不起作用的。你需要检查哪些Cookie是你应用运行所必须的,即时用户没有接受GDPR协议,并且把它们标记为IsEssential

这是我博客系统中的一个例子:

private void SetPostTrackingCookie(CookieNames cookieName, string id)

{

    var options = new CookieOptions

    {

        Expires = DateTime.UtcNow.AddDays(1),

        SameSite = SameSiteMode.Strict,

        Secure = Request.IsHttps,

 

        // Mark as essential to pass GDPR

        // https://docs.microsoft.com/en-us/aspnet/core/security/gdpr?view=aspnetcore-2.1

        IsEssential = true

    };

 

    Response.Cookies.Append(cookieName.ToString(), id, options);

}

另一个问题是,如果你要使用Session,那么用户必须接受GDPR 策略,否则 Session是不工作的。因为 Session 需要依赖 Cookie 在客户端保存 SessionID 。

640?wx_fmt=png

20

热更新 Views

在传统 ASP.NET MVC 中,Views 文件夹默认不会编译到 DLL 文件中,所以我们能够不需要编译整个应用就能更新razor页面。这在不需要更新C#代码的情况下仅修改文字或一些layout修改的场景下非常实用。我有时候也利用这个特性直接向生产环境发布一些修改后的页面。

640?wx_fmt=png

然而,ASP.NET Core 2.1 默认情况下会将我们的 Views 编译到DLL 中以提高性能。因此,你无法在服务器上直接修改一个视图,因为文件夹中根本就不存在 Views,只有一个 *.Views.dll:

640?wx_fmt=png

如果你仍然希望在ASP.NET Core中热更新Views,需要手工修改csproj文件:

<PropertyGroup>

  <TargetFramework>netcoreapp2.1</TargetFramework>

  <RazorCompileOnBuild>false</RazorCompileOnBuild>

  <RazorCompileOnPublish>false</RazorCompileOnPublish>

</PropertyGroup>

640?wx_fmt=gif

21

编译版本号自增长

在传统 .NET 应用程序里,我们可以修改 “AssemblyInfo.cs” 在每次编译时自动增加版本号。这在编译服务器里十分常用。

[assembly: AssemblyVersion("9.0.*")]

结果是这样:

9.0.6836.29475

不幸的是,.NET Core 目前还没有一个自带的方法来完成这个操作。只有一个三方解决方案可能有用:https://github.com/BalassaMarton/MSBump

640?wx_fmt=gif

能看到这里的都是我的真爱粉啊……

结束

ASP.NET Core 相对传统 ASP.NET 有了不少区别,目前也有一定的限制。本文仅涵盖了我自己所遇到的问题,也一定还有很多我没有遇到过的情况。欢迎留言或Email给我交流你的发现。


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

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

相关文章

[翻译] 初看 ASP.NET Core 3.0 即将到来的变化

原文: A first look at changes coming in ASP.NET Core 3.0在我们努力完成下一个 minor 版本的 ASP.NET Core 的同时&#xff0c;我们也在对下一个 major 版本进行更新&#xff0c;其中包括如何使用框架组合项目、更紧密的 .NET Core 集成以及第三方开源集成&#xff0c;所有这…

aspnet core 2.1中使用jwt从原理到精通二

在aspnet core中&#xff0c;自定义jwt管道验证有了上一节的内容作为基础&#xff0c;那这点也是非常容易的&#xff0c;关键点在中间件&#xff0c;只是把上一级在测试类中的自定义验证放到中间件中来即可&#xff0c;不过需要注意&#xff1a;中间件 的位置很重要&#xff0c…

CentOS开发ASP.NET Core入门教程

因为之前一直没怎么玩过CentOS&#xff0c;大多数时间都是使用Win10进行开发&#xff0c;然后程序都部署在Window Server2008或者Window Server2012上&#xff01;因此想尝试下Linux系统。最后经过选型选了比较流行的CentOS系统。正好&#xff0c;今晚要加班&#xff0c;所以在…

工厂参观记:.NET Core 中 HttpClientFactory 如何解决 HttpClient 臭名昭著的问题

在 .NET Framework 与 .NET Core 中 HttpClient 有个臭名昭著的问题&#xff0c;HttpClient 实现了 IDispose 接口&#xff0c;但当你 Dispose 它时&#xff0c;它不会立即关闭所使用的 tcp 连接&#xff0c;而是将 tcp 连接置为 TIME_WAIT 状态&#xff0c;240秒&#xff08;4…

ASP.NET Core2读写InfluxDB时序数据库

在我们很多应用中会遇到有一种基于一系列时间的数据需要处理&#xff0c;通过时间的顺序可以将这些数据点连成线&#xff0c;再通过数据统计后可以做成多纬度的报表&#xff0c;也可通过机器学习来实现数据的预测告警。而时序数据库就是用于存放管理这种有着时间顺序数据的&…

Nature 新研究发布,GPT 驱动的机器人化学家能够自行设计和进行实验,这对科研意味着什么?

文章目录 前言揭秘Coscientist不到四分钟&#xff0c;设计并改进了程序能力越大&#xff0c;责任越大 前言 有消息称&#xff0c;AI 大模型 “化学家” 登 Nature 能够自制阿司匹林、对乙酰氨基酚、布洛芬&#xff0c;甚至连复杂的钯催化交叉偶联反应&#xff0c;也能完成。 …

SmartCode 常见问题

SmartCode 能干什么&#xff1f;SmartCode IDataSource -> IBuildTask -> IOutput > Build EverythingSmartCode的执行流是 数据源->构建任务->输出&#xff0c;也就是说应用场景非常广泛。从DB读取数据结构&#xff0c;最终生成整个解决方案代码生成器&#x…

全面支持开源,微软加速 Visual Studio 和 Azure DevOps 云升级

在 2018 微软技术暨生态大会&#xff08;Microsoft Tech Summit&#xff09;上&#xff0c;微软宣布围绕 Visual Studio 和 Visual Studio Code 开发平台提供一系列新功能与服务&#xff0c;并对 Azure DevOps 研发云进行整合升级&#xff0c;通过 Visual Studio 开发平台与微软…

HttpClient参观记:.net core 2.2 对HttpClient到底做了什么?

.net core 于 10月17日发布了 ASP.NET Core 2.2.0 -preview3&#xff0c;在这个版本中&#xff0c;我看到了一个很让我惊喜的新特性&#xff1a;HTTP Client Performance Improvements &#xff0c;而且在Linux上性能提升了60% !之前就一直苦于 HttpClient 的糟糕特性&#xff…

后缀数组(讲解)

子串&#xff1a;从原串中选取连续的一段&#xff0c;即子串 空串也是子串 后缀&#xff1a;suf(k)为s(k…n)构成的子串 任何子串都是某个后缀的前缀 最长公共前缀 lcp(suf(i),suf(j)) 问题&#xff1a; 将所有后缀suf(1),suf(2),suf(N)按照字典序从小到大排序 暴力sort N2 …

2018 上海.NET职位围观报告

我一直说我是夏眠动物&#xff0c;如今已经11月份了&#xff0c;差不多也该活过来了&#xff0c;所以我决定写篇文章给各位.NET的支持者们和公司打打气&#xff0c;也算是为社区做点贡献吧。我最近主要干了两件事&#xff1a;让NPOI支持.NET Core&#xff0c;现已发布2.4版本。…

老张 .NetCore与Vue 框架学习

缘起作为一个.Net攻城狮已经4年有余了&#xff0c;一直不温不火&#xff0c;正好近来项目不是很忙&#xff0c;闲得无聊&#xff0c;搞一搞新技术&#xff0c;一方面是打发无聊的时间&#xff0c;一方面也是督促自己该学习辣&#xff01;身边的大神都转行的转行&#xff0c;加薪…

2018年10月28日宁波dotnet社区活动回顾及下次活动预告

离上次活动&#xff0c;有半年了&#xff0c;汗。之后尽量保证每月一次&#xff0c;以组织为主&#xff0c;多邀请嘉宾来分享。本次活动不足之处人手不足&#xff1a;由于活动组织事项受限于人手&#xff08;目前就我一个&#xff0c;这次活动前后我又应邀给大红鹰学院应届生介…

[JSOI2007]字符加密

题目描述 喜欢钻研问题的JS 同学&#xff0c;最近又迷上了对加密方法的思考。一天&#xff0c;他突然想出了一种他认为是终极的加密办法&#xff1a;把需要加密的信息排成一圈&#xff0c;显然&#xff0c;它们有很多种不同的读法。 例如‘JSOI07’&#xff0c;可以读作&…

BotSharp v0.2 发布, 支持微信智能回复

BotSharp v0.2 主要是针对微信的消息平台做整合&#xff0c;让.NET开发者可以轻松的搭建基于NLU自然语言理解的智能回复功能&#xff0c;BotSharp.Channel.Weixin模块负责和微信的公众号平台对接&#xff0c;接收消息通知&#xff0c;并能消息产生智能回复&#xff0c;回复的内…

P2852 [USACO06DEC]Milk Patterns G

题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can’t predict the quality of milk from one day to the next, there are some regular patterns in th…

c# 弹性和瞬态故障处理库Polly 学习

关于PollyPolly是一个基于.NET的弹性及瞬态故障处理库,允许开发人员以顺畅及线程安全的方式执行重试(Retry)、断路(Circuit Breaker)、超时(Timeout)、隔离(Bulkhead Isolation)和回退策略(Fallback ).Polly适用于 .NET 4.0, .NET 4.5 和.NET Standard 1.1。以上是官方文档对po…

TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗

TechEmpower在10月30发布最新一轮&#xff08;Round 17&#xff09;针对“Web Framework Benchmarks”的性能测试报告&#xff0c;ASP.NET Core依旧表现不俗&#xff0c;在一些指标上甚至是碾压其他主流Web框架。为此我们做了一个简单的统计&#xff0c;看看ASP.NET Core和其他…

国内开源社区巨作AspectCore-Framework入门

前些天和张队(善友),lemon(浩洋),斌哥(项斌)等MVP大咖一块儿吃饭,大家聊到了lemon名下的AOP这个项目,我这小白听得一脸懵逼,后面回来做了一下功课,查了下资料,在lemon的Github上把这个项目学习了一下,收获颇丰,让我这个没有接触过AOP的Coder叹为观止,陷入了对lemon的深深崇拜,在…

HarmonyOs4.0基础(一)

目录 一、HarmonyOs系统定义 1.1系统的技术特性(三大特征) 1.1.1、硬件互助、资源共享 1.1.2、一次开发、多端部署(面向开发者) 1.1.3、统一OS&#xff0c;弹性部署(支持多种API&#xff1a;ArkTs、JS、C/C、Java) 1.2、系统的技术架构 二、Harmony OS项目搭建 2.1、(D…