Core 3.1 MVC 抛异常“InvalidOperationException: No service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered.”

.NET Core 的版本是 3.1
遇到的问题是 Action 中 return View() 的时候报错

An unhandled exception occurred while processing the request.

InvalidOperationException: No service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered.

Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)

 

错误内容的字面意思是 ITempDataDictionaryFactory 这玩意没有注册。

解决方案一:

修改 Startup.cs 中的 ConfigureServices方法

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

解决方案二:
修改 Startup.cs 中的 ConfigureServices方法

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

查看AspNetCore.Mvc 的源码

        public static IMvcBuilder AddMvc(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            services.AddControllersWithViews();
            return services.AddRazorPages();
        }

AddMvc 方法中包含了 AddControllersWithViews
        public static IMvcBuilder AddControllersWithViews(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var builder = AddControllersWithViewsCore(services);
            return new MvcBuilder(builder.Services, builder.PartManager);
        }

跳转到 AddControllersWithViewsCore

        private static IMvcCoreBuilder AddControllersWithViewsCore(IServiceCollection services)
        {
            var builder = AddControllersCore(services)
                .AddViews()
                .AddRazorViewEngine()
                .AddCacheTagHelper();

            AddTagHelpersFrameworkParts(builder.PartManager);

            return builder;
        }

跳转到 AddViews

        public static IMvcCoreBuilder AddViews(this IMvcCoreBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.AddDataAnnotations();
            AddViewComponentApplicationPartsProviders(builder.PartManager);
            AddViewServices(builder.Services);
            return builder;
        }

跳转到 AddViewServices

        internal static void AddViewServices(IServiceCollection services)
        {
            services.AddDataProtection();
            services.AddAntiforgery();
            services.AddWebEncoders();

            services.TryAddEnumerable(
                ServiceDescriptor.Transient<IConfigureOptions<MvcViewOptions>, MvcViewOptionsSetup>());
            services.TryAddEnumerable(
                ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, TempDataMvcOptionsSetup>());

            //
            // View Engine and related infrastructure
            //
            services.TryAddSingleton<ICompositeViewEngine, CompositeViewEngine>();
            services.TryAddSingleton<IActionResultExecutor<ViewResult>, ViewResultExecutor>();
            services.TryAddSingleton<IActionResultExecutor<PartialViewResult>, PartialViewResultExecutor>();

            // Support for activating ViewDataDictionary
            services.TryAddEnumerable(
                ServiceDescriptor
                    .Transient<IControllerPropertyActivator, ViewDataDictionaryControllerPropertyActivator>());

            //
            // HTML Helper
            //
            services.TryAddTransient<IHtmlHelper, HtmlHelper>();
            services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>));
            services.TryAddSingleton<IHtmlGenerator, DefaultHtmlGenerator>();
            services.TryAddSingleton<ModelExpressionProvider>();
            // ModelExpressionProvider caches results. Ensure that it's re-used when the requested type is IModelExpressionProvider.
            services.TryAddSingleton<IModelExpressionProvider>(s => s.GetRequiredService<ModelExpressionProvider>());
            services.TryAddSingleton<ValidationHtmlAttributeProvider, DefaultValidationHtmlAttributeProvider>();

            services.TryAddSingleton<IJsonHelper, SystemTextJsonHelper>();

            // Component services for Blazor server-side interop
            services.TryAddSingleton<ServerComponentSerializer>();

            //
            // View Components
            //

            // These do caching so they should stay singleton
            services.TryAddSingleton<IViewComponentSelector, DefaultViewComponentSelector>();
            services.TryAddSingleton<IViewComponentFactory, DefaultViewComponentFactory>();
            services.TryAddSingleton<IViewComponentActivator, DefaultViewComponentActivator>();
            services.TryAddSingleton<
                IViewComponentDescriptorCollectionProvider,
                DefaultViewComponentDescriptorCollectionProvider>();
            services.TryAddSingleton<IActionResultExecutor<ViewComponentResult>, ViewComponentResultExecutor>();

            services.TryAddSingleton<ViewComponentInvokerCache>();
            services.TryAddTransient<IViewComponentDescriptorProvider, DefaultViewComponentDescriptorProvider>();
            services.TryAddSingleton<IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>();
            services.TryAddTransient<IViewComponentHelper, DefaultViewComponentHelper>();

            //
            // Temp Data
            //
            services.TryAddEnumerable(
                ServiceDescriptor.Transient<IApplicationModelProvider, TempDataApplicationModelProvider>());
            services.TryAddEnumerable(
                ServiceDescriptor.Transient<IApplicationModelProvider, ViewDataAttributeApplicationModelProvider>());
            services.TryAddSingleton<SaveTempDataFilter>();

            //
            // Component rendering
            //
            services.TryAddScoped<IComponentRenderer, ComponentRenderer>();
            services.TryAddScoped<StaticComponentRenderer>();
            services.TryAddScoped<NavigationManager, HttpNavigationManager>();
            services.TryAddScoped<IJSRuntime, UnsupportedJavaScriptRuntime>();
            services.TryAddScoped<INavigationInterception, UnsupportedNavigationInterception>();

            services.TryAddTransient<ControllerSaveTempDataPropertyFilter>();

            // This does caching so it should stay singleton
            services.TryAddSingleton<ITempDataProvider, CookieTempDataProvider>();
            services.TryAddSingleton<TempDataSerializer, DefaultTempDataSerializer>();

            //
            // Antiforgery
            //
            services.TryAddSingleton<ValidateAntiforgeryTokenAuthorizationFilter>();
            services.TryAddSingleton<AutoValidateAntiforgeryTokenAuthorizationFilter>();

            // These are stateless so their lifetime isn't really important.
            services.TryAddSingleton<ITempDataDictionaryFactory, TempDataDictionaryFactory>();
            services.TryAddSingleton(ArrayPool<ViewBufferValue>.Shared);
            services.TryAddScoped<IViewBufferScope, MemoryPoolViewBufferScope>();
        }

找到了 services.TryAddSingleton<ITempDataDictionaryFactory, TempDataDictionaryFactory>(); 

这一段绑定的代码。

原文地址:https://www.cnblogs.com/ansheng/p/14239237.html