Я использую asp.net mvc 4 и структуру сущности 5 в проекте. У меня есть базовый Entity, что все объекты, производный от него:StackOverflowException был необработанным: необработанное исключение типа «System.StackOverflowException» произошло в mscorlib.dll
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; }
}
Сначала Entity учетная запись является классом для пользователя приложения:
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 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; }
}
Когда я хочу дать роли для конкретного пользователя, вызовите метод GetRoles в Accountrepository. это реализуется следующим образом:
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 запрос. это исключение:
StackOverflowException был необработанным
Необработанного исключение типа «System.StackOverflowException» произошло в mscorlib.dll
{Не могу оценить выражение, так как текущий поток в состояние переполнения стека.}
Метод GetRoles вызывает два раза:
один раз из атрибутов Пользовательские Authorize:
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;
}
}
и второй раз от метода Application_AuthenticateRequest в Global.asax.cs:
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;
}
}
Согласно вашей идее, в чем проблема? Отношения
Почему отрицательный класс? я не понимаю –
Я бы предположил, что нижний предел для большого объема информации - вы не сузили это до места возникновения проблемы.Вероятно, ваш stackoverlow происходит из-за чрезмерной рекурсии - я бы предложил проверить внешние ключи вашего объекта, чтобы убедиться, что вы не настроили круговую ссылку. – Paddy
Я проверяю круглые ссылки, нет никаких круговых ссылок. эти коды работают нормально, но когда я добавляю вторую ** отдельную ** базу данных, используя сначала код ef для ведения журнала, эта ошибка произошла. –