【问题标题】:ASP Net Core 3, set global variable from database and use in view, controllersASP Net Core 3,从数据库设置全局变量并在视图、控制器中使用
【发布时间】:2021-03-06 14:18:38
【问题描述】:

首先请原谅我的英语不好......

我正在寻找一种在我的所有项目中使用类的方法。我向你解释我的需要。因为我不知道去哪里。 我有一个连接到 sql server 的 web 项目 asp net core。在里面我有一个不同部分的公共页面(例如:支付,创建,消息,广告,注册......),我有一个区域管理员(我的后台)。

我有一堂课:

public class Section
{
   public bool RegistrationEnabled { get; set; }
   public bool PaymentEnabled { get; set; }
   public bool PublicationEnabled { get; set; }
   public bool MessageEnabled { get; set; }
}

我希望这个类允许我在我的视图或控制器中使网站的某些部分可访问或不可访问。 前在视图中:

@if (Section.RegistrationEnabled)
{ 
   // Display form register..
}

数据保存在sql server(带有实体框架)的表中,我必须能够从我的管理区域修改它。我希望它是持久的,而不必在每次用户调用页面时都获取它。 我探索了不同的解决方案:

  • appSetting:但我认为我无法从管理界面进行编辑?
  • 资源文件:但我觉得不能直接编辑?
  • 单例?
  • 天蓝色?

我没有想法,我不知道该去哪里......

【问题讨论】:

    标签: c# entity-framework asp.net-core configuration global-variables


    【解决方案1】:

    这是一个有点宽泛/一般的问题,但不是一个难以解决的问题。

    1. 您可以在数据库中创建一个表,例如AppSettings,带有 NameValue 字符串列。您可能希望首先使用普通的 EF Core 代码方法来执行此操作,创建模型,然后进行迁移。

    2. a) 然后,您需要创建一个组件,该组件将自动从数据库中读取这些值并将它们插入到应用程序配置中。例如this seems to be a good implementation candidate

    但是,这引出了一个问题,您希望何时/如何更新它,因为您提到您不希望在每个请求中从数据库中读取它。不过,如果你想让它动态可配置,你将需要一些重新阅读。除非您每次修改配置时都愿意重新启动服务。

    1. b) 另一个选项,而不是上面的配置注入器,是创建一个自定义服务,例如AppSettingsService(或者最好是一个不太通用的名称),您可以在容器中注册为单例范围的服务,并注入到您的消费类中。该服务将从数据库中读取值,将它们缓存在内存中,并以易于使用的方式公开它们;此外,它还可以公开一种从数据库中刷新值的方法。

    如果您需要有关上述任一实现细节的帮助,请告诉我,我可以通过编辑此答案添加更多细节和代码示例。在不了解您的偏好的情况下,详细介绍所有内容将太费力了。

    【讨论】:

      【解决方案2】:

      你可以在asp.net core中使用动态配置来完成这个,我认为这是最好的方式,我推荐你使用这种方式。您可以找到分步指南here

      否则您可以在应用程序启动时从数据库中获取您的一组值并将它们存储在会话中。 [Source]

      首先安装 nuget 包 - Microsoft.AspNetCore.Session

      在 Startup.cs 文件中

          public void ConfigureServices(IServiceCollection services)
          {
              services.AddDistributedMemoryCache();
      
              // Add these 6 lines
              services.AddSession(options =>
              {
                  options.IdleTimeout = TimeSpan.FromSeconds(10);
                  options.Cookie.HttpOnly = true;
                  options.Cookie.IsEssential = true;
              });
              .
              .
              .
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
              else
              {
                  app.UseExceptionHandler("/Home/Error");
                  app.UseHsts();
              }
      
              app.UseHttpsRedirection();
              app.UseStaticFiles();
      
              app.UseRouting();
      
              app.UseAuthentication();
              app.UseAuthorization();
      
              app.UseSession(); //< --- And add this line
              ..............
          }
      

      在 C# 中,您可以设置和检索会话存储中的值

      using Microsoft.AspNetCore.Http;
      
      public class SomeController : Controller
      {    
          public ActionResult Index()
          {   
            HttpContext.Session.SetString("RegistrationEnabled", true ); // Set Session  
            var registrationEnabled = HttpContext.Session.GetString("RegistrationEnabled"); // Get Value of Session
          }    
      }
      

      【讨论】:

        【解决方案3】:

        谢谢,根据您的回答,我试图制作一些可行的东西,但我不知道它是否非常相关。 这是我的设置类:

        [Table("SETTING")]
        public class Setting : BaseObject
        {
           [Key]
           [StringLength(50)]
           public string Key { get; set; }
           [StringLength(50)]
           public string Value { get; set; }
           public e_SettingType Type { get; set; }
        }
        public enum e_SettingType
        {
           UNDEFINED,
           BOOL,
           BYTE,
           CHAR,
           DECIMAL,
           DOUBLE,
           FLOAT,
           INT,
           STRING,
        }
        

        还有我的服务:

        public class SettingService
            {
                private const string CACHE_KEY = "CurrentSetting";
                private readonly IMemoryCache _cache;
                private readonly IBaseRepository<Setting> _setting;
                public SettingService(IMemoryCache cache, IBaseRepository<Setting> setting)
                {
                    _cache = cache;
                    _setting = setting;
                }
                public async Task<bool> GetBool(string key)
                {
                    var settings = await GetFromCache();
                    if (settings != null && settings.Any(x => x.Key.Equals(key)))
                        return bool.Parse(settings.First(x => x.Key.Equals(key)).Value);
                    else
                        return default;
                }
                public async Task<string> GetString(string key)
                {
                    var settings = await GetFromCache();
                    if (settings != null && settings.Any(x => x.Key.Equals(key)))
                        return settings.First(x => x.Key.Equals(key)).Value;
                    else
                        return default;
                }
                private async Task<List<Setting>> GetFromCache()
                {
                    if (!_cache.TryGetValue(CACHE_KEY, out List<Setting> data))
                    {
                        var models = await _setting.FindAll();
                        data = models.ToList();
        
                        var cacheOptions = new MemoryCacheEntryOptions()
                            .SetAbsoluteExpiration(TimeSpan.FromMinutes(30));
        
                        _cache.Set(CACHE_KEY, data, cacheOptions);
                        return data;
                    }
                    else
                        return data;
                }
            }
        

        我已经在 Startup.cs 中添加了这个

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<SettingService>();
        }
        

        为了在我看来使用我的设置,我使用这个:

        @inject MyProject.Service.SettingService setting //top of view
        

        进入我的视野:

        @setting.GetString("MY_KEY").Result
        

        但这有关系吗?还是好的做法?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-11
          • 1970-01-01
          相关资源
          最近更新 更多