2011-08-03 21 views
2

我有一个控制器,它继承自一个抽象的安全控制器,它持有一个用户对象,如下所示。构造函数不一致调用

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; 
} 

上面虽然我的API构造函数调用安全控制器的像这样

基构造
public ApiController(IUserRepository userRepository) : base(userRepository) 
{ 
} 

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

更奇怪的是页面上还有其他的函数引用this.User并且它们都没有返回null异常。他们击中了安全构造函数,然后是api构造函数,然后是函数。 以上甚小孔径终端功能(只命名为测试目的)打功能,然后在换行

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我相信这可能只是一个简单的例子,你的基构造器在某些情况下被赋予一个空引用。在'UserRespository'属性设置器上,尝试测试传入的'value'('if(value == null)throw new Exception(“null!why?”);')并抛出一个特定的异常(如果它为null)检查。 –

回答

2

对不起,我发现问题是由t4mvc模板造成的。

更改ApiController后,需要重新运行代码生成模板以反映更改。

构造函数现在按预期发射。

+0

! –

3

我不知道有足够的代码来了解究竟哪里出了问题来了,但是我注意到,您的User属性使用new关键字来隐藏其下的性能。这只有在调用代码使用对ApiController的引用时才有效(我认为这是new User属性的类型?)。

如果你有一个使用SecureController并尝试访问代码User它不会碰你身边this.user实现零校验码。

至于不一致的构造函数调用,我可以说如果你是new-对象,继承路径上的所有相关构造函数将被调用,除非抛出异常。

在这里看到有关会员的概述使用new关键字隐藏,以及相关的缺陷:

更新:我怀疑Ninject被打傻-家伙你物体寿命。如果不是这样,建设做一些时髦的是这样的:

How does WCF deserialization instantiate objects without calling a constructor?

我说你的断点基类的构造函数,并确保所提供的对象不为空。没有看到更多的代码,很难回答。尝试创建另一个问题,但更多地关注Ninject是问题的可能来源。

+0

谢谢你的回复。删除新的关键字会导致一个警告:“关键字new是用户需要的,因为它隐藏了属性IPrincipal System.Web.Mvc.Controller.User。它在到达用户属性之前确实应该碰到基础构造函数 – JConstantine

+0

仅当构造对象时在使用之前,如果你正在重新使用一个可用的对象,它不会,你所做的就是隐藏下面一个类的成员,如果你的目标是调整该属性的行为,那么基类应该标记为“虚拟'和派生类应该'覆盖'它 –

+0

@JLevett我假设那么你传递给基础构造函数的参数是空的,因为代码看起来应该工作 - 虽然成员隐藏是一个可能的问题点。 –