My application's business-logic layer performs its own authorization checks and all data-querying operations return a GuardedResult<TResult>
value, here's the definition:
public class GuardedResult<TResult> {
public TResult Result { get; }
public Status Status { get; }
public GuardedResult(TResult result, Status status) {
this.Result = result;
this.Status = status;
}
public static implicit operator GuardedResult<TResult>(TResult result) {
return new GuardedResult<TResult>(result, Status.Success);
}
}
Used like so:
public partial class EmployeesBusinessLogic {
public GuardedResult<Employee> GetEmployee(Int64 employeeId) {
if( this.CurrentUser.CanReadAll ) {
return this.Data.Employees.GetEmployeeById( employeeId );
}
else if( this.CurrentUser.CanReadSelf ) {
if( this.CurrentUser.EmployeeId == employeeId ) {
return this.Data.Employees.GetEmployeeById( employeeId );
}
else {
return new GuardedResult<Employee>( null, Status.AccessDenied );
}
}
else {
return new GuardedResult<Employee>( null, Status.AccessDenied );
}
}
}
This builds and works fine.
However when I change TResult
to a closed-generic IQueryable
it fails:
public GuardedResult<IQueryable<Employee>> GetEmployees() {
if( this.CurrentUser.CanReadAll ) {
return this.Data.Employees.GetAllEmployees();
}
else {
return new GuardedResult<IQueryable<Employee>>( null, Status.AccessDenied );
}
}
The compiler error is:
Error CS0266
Cannot implicitly convert type 'System.Linq.IQueryable<Initech.Employee>
' to 'Initech.GuardedResult<System.Linq.IQueryable<Initech.Employee>>
'.
An explicit conversion exists (are you missing a cast?)
Here is the the relevant definitions from the EmployeesData
class:
public IQueryable<Employee> GetAllEmployees() {
return this.dbContext.Employees;
}
public Employee GetEmployeeById(Int64 employeeId) {
return this.dbContext.Employees.SingleOrDefault( e => e.EmployeeId == employeeId );
}