我有以下自定义模型活页夹:
public class AllowAndSanitizeHtmlBinder : IModelBinder
{
// initialize HtmlSanitizer (I want this to be injected)
private HtmlSanitizer _htmlSanitizer = new HtmlSanitizer();
sanitizer.PostProcessNode += (s, e) =>
(e.Node as IHtmlAnchorElement)?.SetAttribute("rel", "nofollow");
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var name = bindingContext.ModelName;
// get the unvalidated user input
var unsanitizedMessageHtmlString = request.Unvalidated[name];
// removed script or any XSS threat from user input
return _htmlSanitizer.Sanitize(unsanitizedMessageHtmlString);
}
}我在这段代码中遇到的问题是,我在模型绑定类中执行HtmlSanitizer的所有初始化(这违反了SRP)。是否可以将HtmlSanitizer注入上述粘合剂中?我使用的是Ninject。
我看过this question:公认的答案是模型绑定器不应该依赖于任何服务,我不确定这里是不是这样……我认为DI会简化我的代码。
发布于 2019-08-14 21:08:01
您需要一个自定义的IModelBinderProvider来实现这一点。
public class AllowAndSanitizeHtmlBinderProvider : IModelBinderProvider
{
public HtmlSanitizer Sanitizer{get;}
public AllowAndSanitizeHtmlBinderProvider(HtmlSanitizer sanitizer)
{
Sanitizer = sanitizer;
}
public IModelBinder GetBinder(Type modelType)
{
if(modelType==typeof(string)) // I assume it's string
return new AllowAndSanitizeHtmlBinder (Sanitizer);
return null;
}
}
public class AllowAndSanitizeHtmlBinder : IModelBinder
{
private HtmlSanitizer _htmlSanitizer;
public AllowAndSanitizeHtmlBinder(HtmlSanitizer sanitizer)
{
_htmlSanitizer = sanitizer;
}
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var name = bindingContext.ModelName;
// get the unvalidated user input
var unsanitizedMessageHtmlString = request.Unvalidated[name];
// removed script or any XSS threat from user input
return _htmlSanitizer.Sanitize(unsanitizedMessageHtmlString);
}
}然后在你的Ninject配置中
kernel.Bind<IModelBinderProvider>().To<AllowAndSanitizeHtmlBinderProvider >();
kernel.Bind<HtmlSanitizer>().ToMethod(ctx => {
var sanitizer = new HtmlSanitizer();
sanitizer.PostProcessNode += (s, e) =>
(e.Node as IHtmlAnchorElement)?.SetAttribute("rel", "nofollow");
return sanitizer;
});一种更好的方法是为AllowAndSanitizeHtmlBinder定义一个工厂,该工厂将保持对HtmlSanitizer的依赖。然后,提供程序将只接收工厂作为依赖项。这将向提供程序屏蔽对HtmlSanitizer的依赖。
此外,它还允许将HtmlSanitizer隐藏在接口后面,并让所有非HtmlSanitizer代码寻址此接口。这将允许对代码的其他部分隐藏这种技术依赖性。
https://stackoverflow.com/questions/57486948
复制相似问题