2011-08-03 9 views
2

다음과 같이 사용자 객체를 보유하는 추상 보안 컨트롤러를 상속 한 컨트롤러가 있습니다. 내 API를 생성자가 너무생성자가 일관되게 호출되지 않았습니다.

같은 안전 컨트롤러의 기본 생성자를 호출해도

public new User User 
{ 
    get 
    { 
    if (this.user == null) 
    { 
     var id = int.Parse(base.User.Identity.Name, CultureInfo.InvariantCulture); 
     this.user = this.UserRepository.FindById(id); 
    } 

    return this.user; 
    } 
} 

나는 다음과 같은 함수를 호출 할 때마다 나는 this.UserRepository

[UrlRoute(Path = "api/stats/events/visits/accounttype/{idList}")] 
[UrlRoute(Path = "api/{idList}/stats/events/visits/accounttype")] 
[UrlRouteParameterDefault(Name = "idList", Value = "")] 
public virtual ActionResult Vsat(string idList, DateTime? startDate, DateTime? endDate) 
{ 
    // get the ids from the url and retrieve a list of events for those user/s 
    var ids = (from id in idList.Split(',') where !string.IsNullOrEmpty(id) select Convert.ToInt64(id)).ToList(); 
    var allEvents = this.eventRepository.FindForCompanyBetweenDatesForUsers(
     this.User.Company.Id, new List<EventType> { EventType.Visit }, startDate, endDate, ids).ToList(); 

    var groupResults = allEvents.GroupBy(x => x.Account.AccountType.Name); 

    return null; 
} 

위의 널 (null) 예외가 발생 더 이상 무엇

public ApiController(IUserRepository userRepository) : base(userRepository) 
{ 
} 

protected SecureController(IUserRepository userRepository) 
{ 
    this.UserRepository = userRepository; 
} 

는 this.User를 참조하고 그들 중 누구도 널 (null) 같은 예외를 반환하지 페이지의 다른 기능이 있다는 것입니다. 그들은 보안 생성자를 누른 다음 API 생성자를 누른 다음 함수를 누릅니다. (테스트 목적으로 단지 이름) 위의 VSAT 함수는, 기능 안타 내가 그 위의 유사한 기능을 배치하면, 작동, 그 같은

this.user = this.UserRepository.FindById(id); 

뿐만 아니라 라인에 중단하지만, 새로운 기능 다음 같은 문제가 있습니다.

편집 새로운 클래스를 생성

과 기능이 완벽하게 작동합니다.

public class TestController : SecureController 
    { 
    private readonly IEventRepository eventRepository; 

    public TestController(IUserRepository userRepository, IEventRepository eventRepository) : base(userRepository) 
    { 
     this.eventRepository = eventRepository; 
    } 

    [UrlRoute(Path = "test/stats/events/visits/accounttype/{idList}")] 
    [UrlRoute(Path = "test/{idList}/stats/events/visits/accounttype")] 
    [UrlRouteParameterDefault(Name = "idList", Value = "")] 
    public virtual ActionResult Vsat(string idList, DateTime? startDate, DateTime? endDate) 
    { 
     // get the ids from the url and retrieve a list of events for those user/s 
     var ids = (from id in idList.Split(',') where !string.IsNullOrEmpty(id) select Convert.ToInt64(id)).ToList(); 
     var allEvents = this.eventRepository.FindForCompanyBetweenDatesForUsers(
     this.User.Company.Id, new List<EventType> {EventType.Visit}, startDate, endDate, ids).ToList(); 

     var groupResults = allEvents.GroupBy(x => x.Account.AccountType.Name); 

     return null; 
    } 
    } 
+0

문제를보다 간단하고 재현 가능한 테스트 케이스로 분리 할 수 ​​있습니까? –

+0

나는이 게시물을 업데이 트했다. 바라건대 그게 무슨 뜻인가? – JConstantine

+0

@JLevett 이것은 특정 상황에서 null 참조가 주어진 기본 생성자의 단순한 사례 일 수 있다고 생각한다. 'UserRespository' 속성 setter에서 들어오는'value' ('if (value == null) throw new Exception ("null! why?");')을 테스트하고, null 일 경우 특정 예외를 throw하십시오. 확인. –

답변

2

혼란에 죄송합니다. t4mvc 템플릿 때문에 문제가 발생한 것으로 나타났습니다.

ApiController를 변경 한 후 변경 사항을 반영하기 위해 코드 생성 템플릿을 다시 실행해야했습니다.

이제 생성자가 예상대로 실행됩니다.

+0

적어도 그것을 발견했습니다! –

3

나는 문제가에오고 정확히 이해하기에 충분한 코드가 잘 모르겠지만, 나는 당신의 User 속성 아래에있는 속성을 숨길 수있는 new 키워드를 사용하는 것으로 나타났습니다. 이것은 호출 코드가 ApiController에 대한 참조를 사용하는 경우에만 작동합니다 (이것은 new User 속성이있는 유형이라고 가정합니다). 당신이 SecureController를 사용하고 액세스하려고 코드가있는 경우

User 당신이 this.user 주위에 구현 널 확인 코드를 만지지 않습니다.

일치하지 않는 생성자 호출의 경우, 객체가 new 인 경우 예외가 throw되지 않는 한 상속 경로의 모든 관련 생성자가 호출된다고 말할 수 있습니다.

new 키워드를 사용하여 숨기기 회원에 대한 개요 여기를 참조 및 관련 함정 :

업데이트 : 나는 Ninject에이 바보 - 놈을 재생 의심하여 개체 수명.

How does WCF deserialization instantiate objects without calling a constructor?

내가 중단하여 기본 클래스 생성자를 말할 제공된 객체가 null이 아닌 확인 것 : 어느 쪽이든 또는 건설은이 같은 펑키 일을하고있다. 더 이상 코드를 보지 않으면 대답하기 어렵습니다. 다른 질문을 시도해보십시오. 그러나 Ninject가 문제의 원인이 될 수 있음에 더 집중하십시오.

+0

답장을 보내 주셔서 감사합니다. 새 키워드를 제거하면 "IPrincipal System.Web.Mvc.Controller.User 속성을 숨기므로 새 키워드가 필요합니다. 사용자 속성에 도달하기 전에 기본 생성자에 실제로 도달해야합니다. – JConstantine

+0

개체가 생성 된 경우에만 사용하기 전에 사용 가능한 객체를 다시 사용하는 경우 사용하지 않을 것입니다. 수행 한 작업은 아래 클래스의 멤버를 숨기는 것입니다. 해당 속성의 동작을 조정하는 것이 목표 인 경우 기본 클래스는 ' 가상'및 파생 된 클래스를 재정의해야합니다. –

+0

@ JLevett 기본 생성자에 전달하는 인수는 null로 간주됩니다. 코드가 제대로 작동해야합니다. 멤버가 숨기는 것이 가능한 문제 일지라도 point. –

관련 문제