Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 构造函数调用不一致_C#_Asp.net Mvc - Fatal编程技术网

C# 构造函数调用不一致

C# 构造函数调用不一致,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个控制器,它继承自一个抽象的安全控制器,该控制器包含一个用户对象,如下所示 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); }

我有一个控制器,它继承自一个抽象的安全控制器,该控制器包含一个用户对象,如下所示

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的null异常

[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构造函数,然后命中函数。 上面的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;
    }
  }
公共类TestController:SecureController
{
私有只读IEventRepository事件存储库;
公共TestController(IUserRepository userRepository,IEventRepository eventRepository):基本(userRepository)
{
this.eventRepository=eventRepository;
}
[UrlRoute(Path=“test/stats/events/visions/accounttype/{idList}”)]
[UrlRoute(Path=“test/{idList}/stats/events/visions/accounttype”)]
[UrlRouteParameterDefault(Name=“idList”,Value=”“)]
公共虚拟操作结果Vsat(字符串idList、DateTime?startDate、DateTime?endDate)
{
//从url获取ID并检索这些用户的事件列表
var id=(来自idList.Split(',')中的id,其中!string.IsNullOrEmpty(id)选择Convert.ToInt64(id)).ToList();
var allEvents=this.eventRepository.findforcompanybetweendesforusers(
this.User.Company.Id,新列表{EventType.Visit},startDate,endDate,ids.ToList();
var groupResults=allEvents.GroupBy(x=>x.Account.AccountType.Name);
返回null;
}
}

我不确定是否有足够的代码来准确理解问题出在哪里,但我注意到您的
用户
属性使用
新建
关键字将属性隐藏在其下方。这仅在调用代码使用对
ApiController
的引用时才有效(我假设这是具有
新用户
属性的类型)

如果您的代码使用了
SecureController
并试图访问
User
,它将不会触及您在
this.User
周围实现的空检查代码

至于不一致的构造函数调用,我可以说,如果您正在
新建一个对象,继承路径上的所有相关构造函数都将被调用,除非抛出异常

有关使用
new
关键字隐藏成员以及相关陷阱的概述,请参见此处:

更新:我怀疑Ninject在玩弄你的对象生命周期。无论是这一点还是建筑业都在做这样的事情:


我要说的是,中断基类构造函数,并确保提供的对象不为null。如果看不到更多的代码,很难回答。尝试创建另一个问题,但更多地关注Ninject可能是问题的根源。

很抱歉造成混淆,原来问题是由t4mvc模板引起的

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


构造器现在按预期被解雇。

您能将问题隔离到一个更简单、可重复的测试用例中吗?我更新了帖子,希望您能做到这一点meant@JLevett我相信这可能只是一个简单的例子,在某些情况下,您的基本构造函数被赋予一个空引用。在
UserRespository
属性设置器上,尝试测试传入的
if(value==null)抛出新异常(“null!为什么?”);
),如果为null则抛出特定异常,只是为了进行健全性检查。感谢您的回复。删除新关键字会导致警告,“用户需要关键字new,因为它隐藏属性IPrincipal System.Web.Mvc.Controller.user。它真的应该在到达用户属性之前命中基本构造函数。如果对象是在使用之前构造的,那么如果您正在使用一个可用的对象,它不会。您所做的是在下面隐藏一个类的成员。如果您的目标是定制该属性的行为,则基类应将其标记为
virtual
,派生类应
重写它。@JLevett我假定您传递给基类构造函数的参数为null,虽然成员隐藏是一个可能的问题,但代码看起来应该可以工作。让我们忘记用户属性,因为它不会导致这里的问题。只需将1而不是this.User.Company.Id传递给FindForCompany函数,即可阻止错误的发生。传递给构造函数的参数是使用ninject提供的,但如前所述,在尝试访问此函数时,在任何时候都不会调用构造函数,这意味着永远不会在SecureController中设置该值class@JLevett啊,Ninject,你把这个对象放在单例模式还是缓存它?中断构造函数并确保提供的用户存储库参数不为null。这里的对象生命周期问题比代码结构问题更多。
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;
    }
  }