我有一个基本api控制器,我希望所有控制器都可以根据请求执行,以充当安全机制。这是控制器
public abstract class SharepointAuthController : ApiController
{
private ClientContext clientContext;
public SharepointAuthController()
: base()
{
ValidateContext();
}
protected void ValidateContext()
{
if (ControllerContext.Request != null)
{
var spContext = SharePointApiControllerContextProvider.Current.GetSharePointContext(ControllerContext);
clientContext = spContext.CreateUserClientContextForSPHost();
if (clientContext == null)
{
throw new AuthenticationException();
}
}
}
protected string GetUserName()
{
User spUser = null;
var spContext = SharePointApiControllerContextProvider.Current.GetSharePointContext(ControllerContext);
using (clientContext = spContext.CreateUserClientContextForSPHost())
{
if (clientContext != null)
{
spUser = clientContext.Web.CurrentUser;
clientContext.Load(spUser, user => user);
clientContext.ExecuteQuery();
return spUser.Email;
}
}
throw new AuthenticationException();
}
}
一个叫它的控制器
public class CallPointsController : SharepointAuthController
{
private readonly ICallPointRepository _callPointRepository;
public CallPointsController(ICallPointRepository callPointRepository)
{
_callPointRepository = callPointRepository;
}
[SharePointContextFilter]
[HttpGet]
[Route("api/callpoints")]
public List<CallPointDto> Get()
{
string user = base.GetUserName();
if (!string.IsNullOrEmpty(user))
{
return _callPointRepository.ListAll();
}
return null;
}
}
我现在想扩展SharepointAuthController以获取有关用户的其他信息(存在于DB中)。我希望能够将存储库传递给基类的构造函数以获得正确的DI,就像这样
private ClientContext clientContext;
private _repo Repo;
public SharepointAuthController(Repo repo)
: base()
{
ValidateContext();
_repo = repo;
}
protected UserDto GetUserName()
{
User spUser = null;
var spContext = SharePointApiControllerContextProvider.Current.GetSharePointContext(ControllerContext);
using (clientContext = spContext.CreateUserClientContextForSPHost())
{
if (clientContext != null)
{
spUser = clientContext.Web.CurrentUser;
clientContext.Load(spUser, user => user);
clientContext.ExecuteQuery();
return _repo.GetAdditionalUserInfo(spUser.Email);
}
}
throw new AuthenticationException();
}
但是这样做不起作用,因为调用此基类的类未正确设置
没有给出与...对应的论据 所需的正式参数&#39; repo&#39;回购
我是以正确的方式来做这件事的吗?我可以从没有DI的Auth控制器调用Repo类
答案 0 :(得分:2)
回答你的问题:
您需要将参数注入到继承的类中并将其传递给父级:
public class SharepointAuthController
{
public SharepointAuthController(Repo repo)
{
ValidateContext();
_repo = repo;
}
// rest of controller ...
}
public class CallPointsController : SharepointAuthController
{
private readonly ICallPointRepository _callPointRepository;
public CallPointsController(ICallPointRepository callPointRepository, Repo repo)
: base(repo)
{
_callPointRepository = callPointRepository;
}
}
另外注意:要进行身份验证,最好不要使用基本控制器。而是创建一个继承自SharepointAuthAttribute
的属性(例如:AuthorizeAttribute
)并在那里进行身份验证。
然后,您可以将该属性应用于需要它的控制器。
答案 1 :(得分:0)
您已在基类中添加了一个参数&#39;构造:
public SharepointAuthController(Repo repo)
: base()
{
//...
}
但是你没有在派生类中提供该参数&#39;构造:
public CallPointsController(ICallPointRepository callPointRepository)
{
//...
}
需要提供:
public CallPointsController(ICallPointRepository callPointRepository, Repo repo)
: base(repo)
{
//...
}
否则派生类将无法构造基类,因此无法成为基类的实例。
答案 2 :(得分:0)
一般不鼓励使用基类。常见的说法是:
基类通常是个坏主意,因为:
因此,组合不是使用基类,而是设计系统的更好方法,尤其是应用跨安全问题(例如安全性)的更好方法。
应用横切关注点的典型方法是使用装饰器。但是,Web API无法使用装饰器包装控制器类型。使用Web API,designed pattern for applying cross-cutting concerns on the controller level是DelegatingHandler
s。