I have a controller which inherits from an abstract secure controller which holds a user object as below.
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;
}
}
Every time I make a call to the following function I receive a null exception for the above 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;
}
Even though my Api constructor calls the base constructor of Secure Controller like so
public ApiController(IUserRepository userRepository) : base(userRepository)
{
}
protected SecureController(IUserRepository userRepository)
{
this.UserRepository = userRepository;
}
What’s even more strange is that there are other functions on the page which reference this.User and none of them return null the same exception. They hit the secure constructor, then the api constructor and then the function.
The above Vsat function (naming just for testing purposes) hits the functions, then breaks on the line
this.user = this.UserRepository.FindById(id);
As well as that, If I place a similar function above that, it works, but the new function then has the same problem.
Edit
Created a new class and the function works perfectly.
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;
}
}
Sorry for the confusion, it turns out the problem was cause by t4mvc templates.
After changing the ApiController the code generation templates needed to be re-ran to reflect the changes.
The constructors are now fired as expected.