Ninject is not working in custom validation attribubte in ASP.NET MVC

丶灬走出姿态 提交于 2019-12-11 01:57:26

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/37947539/ninject-is-not-working-in-custom-validation-attribubte-in-asp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!