首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Ninject向IModelBinder注入类

使用Ninject向IModelBinder注入类
EN

Stack Overflow用户
提问于 2019-08-14 08:59:40
回答 1查看 126关注 0票数 2

我有以下自定义模型活页夹:

代码语言:javascript
复制
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会简化我的代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-14 21:08:01

您需要一个自定义的IModelBinderProvider来实现这一点。

代码语言:javascript
复制
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配置中

代码语言:javascript
复制
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代码寻址此接口。这将允许对代码的其他部分隐藏这种技术依赖性。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57486948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档