Ninject 在 ASP.NET MVC 中的自定义验证属性中不起作用
Ninject is not working in custom validation attribubte in ASP.NET MVC
这个问题是this question的结果。
我正在开发 ASP.NET MVC Web 应用程序。在我的项目中,我正在使用数据注释对我的视图模型进行远程验证 class。我知道默认远程属性不支持服务器验证。我可以在操作方法中再次验证它。但我不想这样做,因为它违反了关注点分离。
所以我尝试创建自定义服务器客户端远程验证属性。我在网上找到了一个代码并使用了它。但是当发生服务器验证时它给我错误。我正在使用 Ninject 进行依赖注入。发生错误是因为 Ninject 无法在验证属性中注入依赖项。
这是我的自定义远程验证属性:
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)
{
}
}
这是我的控制器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);
}
}
当验证通过客户端并到达服务器端时,它开始抛出错误。
这是错误
是的,它抛出没有找到方法异常,因为它找不到没有参数的构造函数。
我像这样添加了无参数构造函数
public CategoryController()
{
categoryRepo = new CategoryRepo();
}
但问题是如果我这样做,我使用 Ninject 的原因就没有任何意义了。它正在产生依赖性。但如果我不这样做,categoryRepo 将在 IsNameUnique 操作中抛出 null 异常。那么如何让 Ninject 在我的自定义远程验证属性中工作?
尝试替换:
object instance = Activator.CreateInstance(controller);
与
object instance = DependencyResolver.Current.GetService(controller);
我必须指出,这是有争议的 ServiceLocator
模式的用法。但是我几乎看不出如何在此属性中做不同的事情。
这个问题是this question的结果。
我正在开发 ASP.NET MVC Web 应用程序。在我的项目中,我正在使用数据注释对我的视图模型进行远程验证 class。我知道默认远程属性不支持服务器验证。我可以在操作方法中再次验证它。但我不想这样做,因为它违反了关注点分离。
所以我尝试创建自定义服务器客户端远程验证属性。我在网上找到了一个代码并使用了它。但是当发生服务器验证时它给我错误。我正在使用 Ninject 进行依赖注入。发生错误是因为 Ninject 无法在验证属性中注入依赖项。
这是我的自定义远程验证属性:
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)
{
}
}
这是我的控制器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);
}
}
当验证通过客户端并到达服务器端时,它开始抛出错误。
这是错误
是的,它抛出没有找到方法异常,因为它找不到没有参数的构造函数。
我像这样添加了无参数构造函数
public CategoryController()
{
categoryRepo = new CategoryRepo();
}
但问题是如果我这样做,我使用 Ninject 的原因就没有任何意义了。它正在产生依赖性。但如果我不这样做,categoryRepo 将在 IsNameUnique 操作中抛出 null 异常。那么如何让 Ninject 在我的自定义远程验证属性中工作?
尝试替换:
object instance = Activator.CreateInstance(controller);
与
object instance = DependencyResolver.Current.GetService(controller);
我必须指出,这是有争议的 ServiceLocator
模式的用法。但是我几乎看不出如何在此属性中做不同的事情。