不安装运行时运行 .NET 程序 - NativeAOT( 二 )

不安装运行时运行 .NET 程序 - NativeAOT

文章插图
访问一下默认生成的那个 Action 方法:http://localhost:5000/WeatherForecast/ 成功的输出了天气信息 。
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
序列化的问题以上通过简单的测试,ASP.NET CORE WebApi 项目顺利的跑起来了, 当然他只是一个简单的示例项目,我们生产的项目相比这些要复杂多了 。经过更深入的测试,发现现阶段 ASP.NET CORE 进行 AOT 发布后有一个比较麻烦的问题,那就是 JSON 序列化 。以下代码是默认生成的 WeatherForecastController 的 GET 方法,这个方法是个标准的同步方法,进行 AOT 发布后序列化没有任何问题 。
[HttpGet]public WeatherForecast[] Get(){return Enumerable.Range(1, 5).Select(index => new WeatherForecast{Date = DateTime.Now.AddDays(index),TemperatureC = Random.Shared.Next(-20, 55),Summary = Summaries[Random.Shared.Next(Summaries.Length)]}).ToArray();}但是如果把代码改成异步,或者说的更直白一点的话,返回值是 Task<T> 类型就会出现问题 。比如把上面的代码使用 Task.FromResult 改造一下,使返回值变成 Task<WeatherForecast[]>
[HttpGet]public async Task<WeatherForecast[]> Get(){var arr = Enumerable.Range(1, 5).Select(index => new WeatherForecast{Date = DateTime.Now.AddDays(index),TemperatureC = Random.Shared.Next(-20, 55),Summary = Summaries[Random.Shared.Next(Summaries.Length)]}).ToArray();var result = await Task.FromResult(arr);return result;}改造的程序进行 AOT 发布后运行,访问对应的接口程序不会有任何报错,但是返回值是个空对象的json:
{}尝试修复该问题,并没有特别的好办法,目前能够勉强使用的办法是使用System.Text.Json source generator 模式进行序列化:首先编写一个 WeatherForecastContext 类继承 JsonSerializerContext,并且标记为 partial 。为啥要标记为 partial ?因为类的另外部分是 source generator 自动生成的 。
[JsonSerializable(typeof(Task<WeatherForecast[]>))]internal partial class WeatherForecastContext : JsonSerializerContext{}第二步,在配置 services 的时候顺便把 WeatherForecastContext 配置进去 。
builder.Services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.AddContext<WeatherForecastContext>());通过以上操作,再次 AOT 发布后运行程序,访问接口,数据是能正确的返回了 。但是有一点小瑕疵是Task对象自身的属性也被序列化出来了 。
{"result": [{"date": "2022-10-08T19:14:26.1801524+08:00","temperatureC": 6,"temperatureF": 42,"summary": "Warm"},{"date": "2022-10-09T19:14:26.1816645+08:00","temperatureC": -9,"temperatureF": 16,"summary": "Bracing"},{"date": "2022-10-10T19:14:26.1816648+08:00","temperatureC": -1,"temperatureF": 31,"summary": "Sweltering"},{"date": "2022-10-11T19:14:26.181665+08:00","temperatureC": -17,"temperatureF": 2,"summary": "Balmy"},{"date": "2022-10-12T19:14:26.1816651+08:00","temperatureC": -16,"temperatureF": 4,"summary": "Freezing"}],"asyncState": null,"creationOptions": 0,"exception": null,"id": 1,"isCanceled": false,"isCompleted": true,"isCompletedSuccessfully": true,"isFaulted": false,"status": 5}桌面程序以上对控制台程序,web 程序进行了测试,接下来顺便对桌面 GUI 程序测试一下吧 。
不安装运行时运行 .NET 程序 - NativeAOT

文章插图
很遗憾,不管是 WINFROM 还是 WPF 程序,进行 AOT 发布的时候直接都会报错,提示不支持 。
一些其他限制AOT 发布的程序会有一些限制,我们编写的时候需要注意:
  1. No dynamic loading (for example, Assembly.LoadFile)
  2. No runtime code generation (for example, System.Reflection.Emit)

    经验总结扩展阅读