프로젝트에서 asp.net mvc 4 및 엔터티 프레임 워크 5를 사용하고 있습니다. 사용자의StackOverflowException 처리되지 않았습니다 : 'System.StackOverflowException'형식의 처리되지 않은 예외가 mscorlib.dll에서 발생했습니다
public class Account : BaseEntity
{
public string UserName { get; set; }
public string Password { get; set; }
public byte[] AvatarBinary { get; set; }
public string AvatarMimeType { get; set; }
public virtual IList<AccountInRole> AccountRoles { get; set; }
}
역할 :
public class Role : BaseEntity
{
public string RoleName { get; set; }
public virtual IList<AccountInRole> AccountRoles { get; set; }
}
각
public abstract class BaseEntity
{
[Required]
public virtual int Id { get; set; }
[Required]
public virtual DateTime CreatedOn { set; get; }
public virtual string CreatedBy { set; get; }
[Required]
public virtual DateTime ModifiedOn { set; get; }
public virtual string ModifiedBy { set; get; }
}
먼저 계정 엔티티 응용 프로그램 사용자를위한 클래스입니다 : 내가 모든 엔티티가 그것에서 파생 된 기본 엔티티가 사용자는 여러 역할을 가질 수 있으며 그 반대의 경우도 가능합니다.
public class AccountInRole : BaseEntity
{
public int AccountId { get; set; }
public int RoleId { get; set; }
public virtual Account Account { get; set; }
public virtual Role Role { get; set; }
}
특정 사용자에 대한 역할을 지정하려면 Accountrepository에서 GetRoles 메서드를 호출하십시오. 이 방법으로이 구현됩니다 :
public class AccountRepository : IAccountRepository
{
#region Properties
private CharityContext DataContext { get; set; }
public IQueryable<Account> Accounts
{
get { return DataContext.Accounts; }
}
#endregion
#region Ctors
public AccountRepository() : this(new CharityContext())
{
}
public AccountRepository(CharityContext db)
{
DataContext = db;
}
#endregion
#region Methods
public List<Role> GetRoles(string userName)
{
var acc = DataContext.Accounts;
var query = from u in DataContext.Accounts
from r in DataContext.Roles
from ur in DataContext.AccountInRoles
where ur.AccountId == u.Id && ur.RoleId == r.Id && u.UserName == userName
select r;
return query.ToList();
}
#endregion
}
이 메서드는 컴파일러에서 위의 LINQ 쿼리를 실행하려면 예외가 throw됩니다. 이 예외는 다음과 같습니다
있는 StackOverflowException이 'System.StackOverflowException'형식의 처리되지 않은 예외가 mscorlib.dll에서 발생
처리되지 않은했다
{현재의 thread가에 있기 때문에 식을 계산할 수 없습니다 스택 오버플로 상태}.
GetRoles 메서드는 두 번 호출합니다.
맞춤 권한 부여 속성 0한번에 :
public class CustomAuthorize : AuthorizeAttribute
{
//private readonly IAccountRepository _accountRepository;
private string[] roles;
//public CustomAuthorize(params string[] roles)
//{
// this.roles = roles;
//}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
throw new ArgumentNullException("httpContext");
if (!httpContext.User.Identity.IsAuthenticated)
return false;
if (Roles == string.Empty)
return true;
var lstRoles = Roles.Split(',');
AccountRepository _accountRepository = new AccountRepository();
var userRoles = _accountRepository.GetRoles(httpContext.User.Identity.Name);
foreach (var role in lstRoles)
{
bool isFound = false;
foreach (var userRole in userRoles)
{
if (userRole.RoleName == role)
isFound = true;
}
if (!isFound) return false;
}
return true;
}
}
및 Global.asax.cs으로하여 Application_AuthenticateRequest 방법에서 두번째 :
ou는protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
string cookie = FormsAuthentication.FormsCookieName;
HttpCookie httpCookie = Request.Cookies[cookie];
if (httpCookie == null) return;
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(httpCookie.Value);
if(ticket == null || ticket.Expired) return;
FormsIdentity identity = new FormsIdentity(ticket);
var _accountRepository = new AccountRepository();
var roles = _accountRepository.GetRoles(identity.Name);
var principal = new CharityAccount(identity.Name, roles.Select(x => x.RoleName).ToArray());
Context.User = Thread.CurrentPrincipal = principal;
}
CharityAccount 상기 방법에서 볼 수있다 이 방법으로 구현 :
public class CharityAccount : IPrincipal
{
private string[] roles;
private IIdentity identity;
public IIdentity Identity
{
get { return identity; }
}
public bool IsInRole(string role)
{
return Array.IndexOf(roles, role) >= 0;
}
public CharityAccount(String name, String[] roles)
{
identity = new GenericIdentity(name, "Custom authentication");
this.roles = roles;
}
}
당신의 아이디어에 따르면, 무엇이 문제입니까? 안부
왜 부정 등급입니까? 나는 이해하지 못한다. –
나는 downvote가 많은 양의 정보를 갖고 있다고 상상할 것이다. 문제가 발생한 곳을 좁히지 않았다.과도한 재귀 때문에 stackoverlow가 발생했을 가능성이 있습니다. 순환 참조를 설정하지 않았는지 확인하기 위해 엔티티 외래 키를 확인하는 것이 좋습니다. – Paddy
순환 참조가 있는지 확인합니다. 순환 참조가 없습니다. 이 코드는 정상적으로 작동하지만 로깅 목적으로 ef 코드를 사용하여 두 번째 ** 별도 ** 데이터베이스를 추가 할 때이 오류가 발생했습니다. –