.NET 6使用Autofac设置Newtonsoft.Json默认选项



我目前正在重新编写.NET 6 WebAPI。在重构时,我转而使用Autofac作为我的DI框架。

为了让我的控制器不返回null值,我使用了带有以下选项的newtonsoft-json:

builder.Services.AddControllers().AddDefaultJsonOptions();
public static IMvcBuilder AddDefaultJsonOptions(this IMvcBuilder builder)
{
return builder.AddNewtonsoftJson(options =>
{
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
}

使用autofac,我将控制器的注册更改为:

builder.Host.ConfigureContainer<Autofac.ContainerBuilder>(builder =>
{
...
var executingAssembly = Assembly.GetExecutingAssembly();
builder.RegisterApiControllers(executingAssembly);
...
});

但是我现在如何更改默认的json序列化选项呢?

ASP.NET Core完全开源的美妙之处在于,您可以自己访问repo,进行一些深入研究,了解这些方法的作用,然后跟踪如何解决此类问题。

在这种情况下,让我们看看AddControllers实际上做了什么:

public static IMvcBuilder AddControllers(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
var builder = AddControllersCore(services);
return new MvcBuilder(builder.Services, builder.PartManager);
}

看起来AddControllersCore中隐藏了很多内容,所以我们可以向下滚动到:

private static IMvcCoreBuilder AddControllersCore(IServiceCollection services)
{
// This method excludes all of the view-related services by default.
var builder = services
.AddMvcCore()
.AddApiExplorer()
.AddAuthorization()
.AddCors()
.AddDataAnnotations()
.AddFormatterMappings();
if (MetadataUpdater.IsSupported)
{
services.TryAddEnumerable(
ServiceDescriptor.Singleton<IActionDescriptorChangeProvider, HotReloadService>());
}
return builder;
}

有趣。因此,AddControllers实际上并没有将字面控制器添加到服务集,而是添加了执行控制器所需的东西。为什么?

我会快进一点——这是因为控制器默认情况下不会被解析为服务惊喜!实际情况是,控制器参数被解析,但控制器本身是通过反射创建的,解析的参数被传递给构造函数。如果您确实希望控制器被解析(例如,支持属性注入或其他(,则需要使用AddControllersAsServices(这也在Autofac文档中(

事实上,您使用的RegisterApiControllers方法甚至不适用于ASP.NET Core,而是适用于ASP.NET Web API,后者不在.NET 6中。您真的需要检查ASP.NET核心集成,并且在重构中绝对不要使用任何经典的ASP.NET和Web API。这不是混搭。这都是.NET核心/ASP.NET核心。

那么,为了回答这个问题,您如何注册控制器获得JSON选项?

继续做你正在做的事情

builder.Services
.AddControllers()
.AddControllersAsServices()
.AddDefaultJsonOptions();

如果你真的想用Autofac手动注册控制器,你可以重新注册它们(在之后你调用AddControllersAsServices(,但你会将它们注册为自己。

builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Services
.AddControllers()
.AddControllersAsServices()
.AddDefaultJsonOptions();
builder.Host
.ConfigureContainer<ContainerBuilder>(b => {
b.RegisterType<MyController>().PropertiesAutowired();
});

但是,同样,除非你特别要做一些事情来覆盖控制器的注册方式,比如需要设置lambda或属性注入之类的,否则AddControllersAsServices会覆盖它

如果您希望Autofac作为您的容器,您确实需要UseServiceProviderFactory调用否则,即使调用ConfigureContainer<T>,也会得到默认的Microsoft容器。

相关内容

  • 没有找到相关文章

最新更新