Недавно я обновил свое приложение до .net core 6, и теперь я получаю эту ошибку при попытке получить услугу, используя этот код:
IUnityContainer container = HangfireUnityConfig.GetConfiguredContainer();
var authService = container.Resolve<IAuthService>();
Я читал некоторые другие сообщения, в которых упоминалось о добавлении HttpContextAccessor в мой метод ConfigureServices(), но ни один из способов, которые я пробовал, не исправил ошибку.
services.AddHttpContextAccessor();
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Другой человек упомянул о добавлении строки в мой Program.cs, но по-прежнему получает сообщение об ошибке.
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Если я добавлю RegisterType<IHttpContextAccessor, HttpContextAccessor>() в RegisterTypes() в моем классе HangFireUnityConfig, ошибка исчезнет, но позже выдаст новую ошибку, поэтому я не уверен, что это правильное исправление.
public static void RegisterTypes(IUnityContainer container)
{
// register hangfire dependencies
container.RegisterType<IHttpContextAccessor, HttpContextAccessor>()
}
AuthService.cs
using MyApp.Entities.DTOs;
namespace MyApp.Service.Auth
{
public class AuthService : IAuthService
{
private UserDto currentUser = null;
private readonly IHttpContextAccessor _context;
public AuthService(IHttpContextAccessor ctx)
{
_context = ctx;
currentUser = parseClaimsUser();
}
public bool isInRole(string role, List<string> roleList)
{
return true;
}
public UserDto parseClaimsUser()
{
ClaimsPrincipal currentClaim = _context.HttpContext.User;
UserDto parsedUser = new UserDto();
bool isAdmin = false;
if (currentClaim == null || !currentClaim.Identity.IsAuthenticated)
{
return parsedUser;
}
//return user id from token properties
parsedUser.userID = currentClaim.Claims.Where(claim => claim.Type == ClaimTypes.NameIdentifier).Select(v => v.Value).FirstOrDefault<string>();
// retrieve groups from token properties --- this is only retrieved upon login. Users will have to log out and log back in to see any changes in groups
var currentGroupsIDs = currentClaim.HasClaim(claim => claim.Type == ClaimTypes.Role) ?
currentClaim.Claims.Where(t => t.Type == ClaimTypes.Role).Select(y => int.Parse(y.Value)).ToList<int>()
: new List<int>();
var adminString = currentClaim.Claims.Where(claim => claim.Type == ClaimTypes.AuthorizationDecision)
.Select(v => v.Value)
.SingleOrDefault<string>();
adminString = adminString == null ? "False" : adminString;
isAdmin = bool.Parse(adminString);
//parsedUser.userGrp = currentGroups;
parsedUser.userGrpIDs = currentGroupsIDs;
parsedUser.isAuthenticated = currentClaim.Identity.IsAuthenticated;
parsedUser.displayName = currentClaim.Identity.Name;
parsedUser.email = currentClaim.Claims.Where(w => w.Type == ClaimTypes.Email).Select(v => v.Value).SingleOrDefault<string>();
//parsedUser.currentToken = tokenExtract;
parsedUser.isAdmin = isAdmin;
var isUS = currentClaim.Claims.Where(claim => claim.Type == "us_citizen").Select(v => v.Value).SingleOrDefault<string>();
if (isUS != null)
{
parsedUser.isUSCitizenAndJPLEmployee = bool.Parse(isUS);
}
return parsedUser;
}
public void initUser()
{
currentUser = parseClaimsUser();
}
public UserDto getCurrentUser(bool includeToken = false)
{
if (currentUser == null || currentUser.userID == null)
{
currentUser = parseClaimsUser();
}
if (!includeToken)
{
currentUser.currentToken = null;
}
return currentUser;
}
public bool userIsAdmin()
{
return true;
}
}
}
Можете ли вы поделиться реализацией IAuthService?
@CKK services.AddHttpContextAccessor() - это то, что у меня было до обновления, но не выдает эту ошибку
@sa-es-ir Я добавил свой IAuthService, но не думаю, что проблема в этом
Нет, я имел в виду класс, реализующий IAuthService!
@sa-es-ir хорошо, я добавил код для своего AuthService, который реализует IAuthService
Я смог выяснить ошибку, которую я получил с моей последней реализацией. Ошибка заключалась в невозможности привести мой dbContext к типу IObjectContextAdapter.
public List<KeyValuePair<string, long>> GetKeys(EntityEntry entry)
{
var keys = new List<KeyValuePair<string, long>>();
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
if (objectStateEntry.EntityKey.EntityKeyValues != null)
{
keys.AddRange(objectStateEntry.EntityKey.EntityKeyValues.Select(key => new KeyValuePair<string, long>(key.Key, Convert.ToInt64(key.Value))));
}
return keys;
}
Я отрефакторил код, чтобы он выглядел так, и ошибок не было.
public List<KeyValuePair<string, long>> GetKeys(EntityEntry entry)
{
//this gets an array of the key names
var keyNames = entry.Metadata.FindPrimaryKey()
.Properties
.Select(p => p.Name)
.ToArray();
var keys = new List<KeyValuePair<string, long>>();
if (keyNames != null)
{
//creates the KeyValuePairs
keys.AddRange(keyNames.Select(key => new KeyValuePair<string, long>(key, Convert.ToInt64(entry.Property(key).CurrentValue))));
}
return keys;
}
Вам нужна только строка
services.AddHttpContextAccessor();
. Остальное мусор