如何处理在ASP.Net Core中在相同上下文范围内运行的静态类? [英] How to handle static classes running in the same context scope in 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屋!