如何处理在ASP.Net Core中在相同上下文范围内运行的静态类? [英] How to handle static classes running in the same context scope in ASP.Net Core?

查看:207
本文介绍了如何处理在ASP.Net Core中在相同上下文范围内运行的静态类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的示例中,我有一个控制器,该控制器生成密钥串行ID 并加密一些敏感信息,例如SSN.我在静态类中有函数,可以在项目的任何地方调用它们.这两个类都在相同的上下文中运行并运行SP.我认为问题出在那儿.

In the following example I have a controller that generates a key serial Id and encrypt some sensitive information like for example SSN. I have my functions in static classes to allow me to call them from anywhere in my project. both classes are running in the same context and run SP. I think the problem lies in there.

startup.cs

startup.cs

    public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<MvcOptions>(options =>
                {
                    options.Filters.Add(new RequireHttpsAttribute());
                });
                services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("ARTNetCore")));

                services.AddIdentity<ApplicationUser, IdentityRole>(config =>
                {
                    config.SignIn.RequireConfirmedEmail = true;
                })
                    .AddEntityFrameworkStores<ApplicationDbContext>()
                    .AddDefaultTokenProviders();

                // Add application services.
                services.AddTransient<IEmailSender, AuthMessageSender>();
                services.AddTransient<ISmsSender, AuthMessageSender>();
                services.Configure<SMSoptions>(Configuration);
                services.AddMvc();
                // Configure Identity
                services.Configure<IdentityOptions>(options =>
                {
                    // Password settings
                    options.Password.RequireDigit = true;
                    options.Password.RequiredLength = 8;
                    options.Password.RequireNonAlphanumeric = false;
                    options.Password.RequireUppercase = true;
                    options.Password.RequireLowercase = false;

                    // Lockout settings
                    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                    options.Lockout.MaxFailedAccessAttempts = 10;
                    options.Lockout.AllowedForNewUsers = true;


                    services.AddCookieAuthentication(o =>
                    {
                        o.LoginPath = "/Account/LogIn";
                        o.LogoutPath = "/Account/LogOut";
                    });


                    // User settings
                    options.User.RequireUniqueEmail = true;
                });
                services.Configure<AuthMessageSenderOptions>(Configuration);

            }
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {

            var options = new RewriteOptions()
               .AddRedirectToHttps();

            app.UseRewriter(options);

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
            //Comment when migrating or demigrating

            //SeedData.Initialize(app.ApplicationServices);

        }

控制器是

private readonly ApplicationDbContext _context;

        public PatRegController(ApplicationDbContext context)
        {
            _context = context;
        }            
            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> Create([Bind("FName,MName,LName,Dob,GenrId,StasId,NatyId,MarsId,CouyId,StaeId,CityId,OccnId,Email,SNN,PassNo,MobNo,LLine,MAdds,StrtNo,SDirn,AptNo,Locy,ALevl,PCode,Couy,ProeId")] PatReg patReg)
            {
                if (ModelState.IsValid)
                {
                    patReg.FileId = DbSerializerHandler.SerializeFileId(_context); 
                    patReg.SNN = DbEncryptionHandler.DynamicEncrypt(patReg.SNN, _context);
                    _context.Add(patReg);
                    await _context.SaveChangesAsync();
                    return RedirectToAction(nameof(Index));
                }
                return View(patReg);
            } 

加密静态类为

 public static class DbEncryptionHandler
    {

        public static string DynamicEncrypt(string clearText, ApplicationDbContext _context)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(clearText))
                {

                    List<EncKeys> Keys = new List<EncKeys>();
                    Keys = _context.EncKeys.FromSql("EncKeysSP").ToList();
                    string EncryptionKey = Keys[0].DynamicKey;
                    byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
                    using (Aes encryptor = Aes.Create())
                    {
                        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                        encryptor.Key = pdb.GetBytes(32);
                        encryptor.IV = pdb.GetBytes(16);
                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                            {
                                cs.Write(clearBytes, 0, clearBytes.Length);
                                cs.Close();
                            }
                            clearText = Convert.ToBase64String(ms.ToArray());
                        }
                    }
                }
                else
                {

                    clearText = null;

                }
            }
            catch (Exception ex)
            {
               throw;
            }

            return clearText;
        }
}

并且Serializer静态类是

and Serializer static class is

 public static class DbSerializerHandler
    {
        public static Int64 SerializeFileId(ApplicationDbContext _context)
        {
            List<FileIdSeq> NewFileSeq = new List<FileIdSeq>();
            NewFileSeq = _context.FileIdSeq.FromSql("FileIdSeqSP").ToList();
            var FileID = NewFileSeq[0].LastSequence;
            return FileID;
        }
    }

当我尝试保存数据时,出现此错误

When I try to save my data I get this error

处理请求时发生未处理的异常.

An unhandled exception occurred while processing the request.

SqlException:不允许新事务,因为还有其他事务会话中运行的线程.System.Data.SqlClient.SqlConnection.OnError(SqlException异常,bool breakConnection,操作wrapCloseInAction)

SqlException: New transaction is not allowed because there are other threads running in the session. System.Data.SqlClient.SqlConnection.OnError(SqlException exception, bool breakConnection, Action wrapCloseInAction)

错误在此控制器行上返回 await _context.SaveChangesAsync();

The error returns on this controller line await _context.SaveChangesAsync();

我在做什么错了?

更新我检查了一下,一次只能运行这些功能之一,而不能一次运行.

update I checked, I can run only one of these functions at a time but not both at the same time.

推荐答案

DbEncryptionHandler DbSerializerHandler 类不需要依赖于 ApplicationDbContext ,只是他们需要的数据.

The DbEncryptionHandler and DbSerializerHandler classes do not need to have a dependency on ApplicationDbContext, just the data they need from it.

public static class DbEncryptionHandler
{
   public static string DynamicEncrypt(string clearText, IEnumerable<EncKeys> keys)
   {
        ...
   }
}

public static class DbSerializerHandler
{
    public static Int64 SerializeFileId(IEnumerable<FileIdSeq> seq)
    {
        ...
    }
}

在控制器中,可以在使用静态类之前从上下文中获取数据.

In your controller you can get the data from your context before you use your static classes.

public async Task<IActionResult> Create(PatReg patReg)
{
    if (ModelState.IsValid)
    {
        var seq = await _context.FileIdSeq.FromSql("FileIdSeqSP").ToListAsync();
        var keys = await _context.EncKeys.FromSql("EncKeysSP").ToListAsync();

        patReg.FileId = DbSerializerHandler.SerializeFileId(seq); 
        patReg.SNN = DbEncryptionHandler.DynamicEncrypt(patReg.SNN, keys);

        _context.Add(patReg);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(patReg);
} 

这篇关于如何处理在ASP.Net Core中在相同上下文范围内运行的静态类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆