Ninject在ASP.NET MVC中的自定义验证属性中不起作用 [英] Ninject is not working in custom validation attribubte in ASP.NET MVC

查看:347
本文介绍了Ninject在ASP.NET MVC中的自定义验证属性中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题是模式。但是我几乎看不出该属性的用法。


This question is the consequence of this question.

I am developing an ASP.NET MVC Web Application. In my project I am doing remote validation using data annotation to my view model class. I know default remote attribute does not support server validation. I can validate it again in action method. But I do not want to do that it is violating separation of concerns.

So I tried to create custom server client remote validation attribute. I found a code online and I used it. But it is giving me error when server validation is occurred. I am using Ninject for dependency injection. Error occurred because Ninject cannot inject dependencies in validation attribute.

This is my custom remote validation attribute:

public class RemoteClientServerAttribute : RemoteAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            // Get the controller using reflection
            Type controller = Assembly.GetExecutingAssembly().GetTypes()
                .FirstOrDefault(type => type.Name.ToLower() == string.Format("{0}Controller",
                    this.RouteData["controller"].ToString()).ToLower());
            if (controller != null)
            {
                // Get the action method that has validation logic
                MethodInfo action = controller.GetMethods()
                    .FirstOrDefault(method => method.Name.ToLower() ==
                        this.RouteData["action"].ToString().ToLower());
                if (action != null)
                {
                    // Create an instance of the controller class
                    object instance = Activator.CreateInstance(controller);
                    // Invoke the action method that has validation logic
                    object response = action.Invoke(instance, new object[] { value });
                    if (response is JsonResult)
                    {
                        object jsonData = ((JsonResult)response).Data;
                        if (jsonData is bool)
                        {
                            return (bool)jsonData ? ValidationResult.Success :
                                new ValidationResult(this.ErrorMessage);
                        }
                    }
                }
            }

            return ValidationResult.Success;
            // If you want the validation to fail, create an instance of ValidationResult
            // return new ValidationResult(base.ErrorMessageString);
        }

        public RemoteClientServerAttribute(string routeName)
            : base(routeName)
        {
        }

        public RemoteClientServerAttribute(string action, string controller)
            : base(action, controller)
        {
        }

        public RemoteClientServerAttribute(string action, string controller,
            string areaName)
            : base(action, controller, areaName)
        {
        }
    }

This is my controller class

public class CategoryController : Controller
    {
        private ICategoryRepo categoryRepo;

        public CategoryController()
        {

        }

        public CategoryController(ICategoryRepo categoryParam)
        {
            this.categoryRepo = categoryParam;
        }
        .
        .
        //remote validation action
         public JsonResult IsNameUnique(string Name)
        {
            IEnumerable<Category> categories = categoryRepo.Categories.Where(x => x.Name.Trim() == Name);

            Category category = categories.FirstOrDefault();
            return Json(category==null, JsonRequestBehavior.AllowGet);
        }
}

When validation passed client side and came to server side, it starts throwing error.

This is the error

Yes, it is throwing no method found exception because it cannot find constructor without parameters.

I added parameterless constructor like this

public CategoryController()
        {
           categoryRepo = new CategoryRepo(); 
        }

But the problem is if I do that, the reason I am using Ninject does not make any sense at all. It is making dependency. But if I don't do this way, categoryRepo will throw null exception in IsNameUnique action. So how can I make Ninject work in my custom remote validation attribute?

解决方案

Try to replace :

object instance = Activator.CreateInstance(controller);

with

object instance = DependencyResolver.Current.GetService(controller);

I must point that this is an usage of the controversial ServiceLocator pattern. But I hardly see how to do it differently in this attribute.

这篇关于Ninject在ASP.NET MVC中的自定义验证属性中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆